{"id":40610949,"url":"https://github.com/hack-dance/island-ai","last_synced_at":"2026-01-21T05:10:37.864Z","repository":{"id":217173267,"uuid":"741678943","full_name":"hack-dance/island-ai","owner":"hack-dance","description":null,"archived":false,"fork":false,"pushed_at":"2025-06-15T01:43:06.000Z","size":3117,"stargazers_count":155,"open_issues_count":3,"forks_count":14,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-11-27T10:26:36.454Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://island.hack.dance","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/hack-dance.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-01-10T22:13:24.000Z","updated_at":"2025-10-12T17:35:04.000Z","dependencies_parsed_at":"2024-04-09T03:29:40.179Z","dependency_job_id":"1a67a75e-332a-4409-a4f0-85881f4b04a9","html_url":"https://github.com/hack-dance/island-ai","commit_stats":null,"previous_names":["hack-dance/island-ai"],"tags_count":48,"template":false,"template_full_name":null,"purl":"pkg:github/hack-dance/island-ai","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hack-dance%2Fisland-ai","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hack-dance%2Fisland-ai/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hack-dance%2Fisland-ai/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hack-dance%2Fisland-ai/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/hack-dance","download_url":"https://codeload.github.com/hack-dance/island-ai/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hack-dance%2Fisland-ai/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28627390,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-21T04:47:28.174Z","status":"ssl_error","status_checked_at":"2026-01-21T04:47:22.943Z","response_time":86,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-01-21T05:10:37.182Z","updated_at":"2026-01-21T05:10:37.858Z","avatar_url":"https://github.com/hack-dance.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n  \u003cimg src=\"https://island.hack.dance/island_light.svg\" alt=\"Island AI\" width=\"200\" style=\"margin: 0 auto 24px; display: block;\" /\u003e\n\u003c/div\u003e\n\u003cbr /\u003e\n\n\u003cp align=\"center\"\u003e\u003ci\u003e\u003e A TypeScript toolkit for building structured LLM data handling pipelines\u003c/i\u003e\u003c/p\u003e\n\u003cbr /\u003e\n\n\u003cdiv align=\"center\"\u003e\n  \u003ca aria-label=\"Docs\" href=\"https://island.hack.dance\"\u003e\n    \u003cimg alt=\"docs\" src=\"https://img.shields.io/badge/DOCS-000000.svg?style=flat-square\u0026labelColor=000000\u0026logo=data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyBpZD0iTGF5ZXJfMiIgZGF0YS1uYW1lPSJMYXllciAyIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyMTQuNjkgMjU5LjI0Ij4KICA8ZGVmcz4KICAgIDxzdHlsZT4KICAgICAgLmNscy0xIHsKICAgICAgICBmaWxsOiAjZmZmOwogICAgICAgIHN0cm9rZS13aWR0aDogMHB4OwogICAgICB9CiAgICA8L3N0eWxlPgogIDwvZGVmcz4KICA8ZyBpZD0iTGF5ZXJfMS0yIiBkYXRhLW5hbWU9IkxheWVyIDEiPgogICAgPGc+CiAgICAgIDxnPgogICAgICAgIDxwYXRoIGNsYXNzPSJjbHMtMSIgZD0ibTEwMC42MSwxNzguNDVoMTMuOTd2LTE5LjYyaC0xMy45N3YxOS42MlptMC0xMDguOTZ2MjMuNzJoMTMuOTd2LTIzLjcyaC0xMy45N1ptLTIuNzksMTg5Ljc1aDE5LjU2bC0yLjc5LTI4LjkyaC0xMy45N2wtMi43OSwyOC45MlptMi43OS0xMzcuNjJoMTMuOTd2LTE5LjYyaC0xMy45N3YxOS42MlptMCwyOC40MWgxMy45N3YtMTkuNjJoLTEzLjk3djE5LjYyWiIvPgogICAgICAgIDxjaXJjbGUgY2xhc3M9ImNscy0xIiBjeD0iOTQuNSIgY3k9IjY5LjExIiByPSIxNC4yNCIvPgogICAgICAgIDxjaXJjbGUgY2xhc3M9ImNscy0xIiBjeD0iMTIwLjE5IiBjeT0iNjkuMTEiIHI9IjE0LjI0Ii8+CiAgICAgICAgPHBhdGggY2xhc3M9ImNscy0xIiBkPSJtMjE0LjI1LDYyLjU5Yy0uNzktLjc1LTE4Ljc1LTE3LjQ4LTQ5LjQ2LTE5LjA0bDE1Ljc1LTUuODhjLTEuNjctMi40Ni00LjAxLTQuMTgtNi4zNS02LS4yMy0uMTgtLjAzLS41OC4yMy0uNTcsMy40NS4xNyw2LjgyLDEuNzUsMTAuMTIsMi42OCwxLjA2LjMsMi4wOS43MiwzLjA4LDEuMjRsMTkuNDUtNy4yNmMuNTMtLjIuOS0uNzEuOTEtMS4yOHMtLjMyLTEuMDktLjg1LTEuMzJjLTEuMDQtLjQ0LTI1Ljk2LTEwLjc2LTU3LjM1Ljk2LTEuMTkuNDQtMi4zNy45MS0zLjU0LDEuNDFsMTMuNTEtMTMuMTNjLTIuMTgtLjY3LTQuNC0uOTUtNi42My0xLjQ0LS4zOC0uMDgtLjQxLS43NSwwLS44MSwzLjEyLS40NCw2LjU0LS45OCw5Ljg3LS45MWw5LjEzLTguODdjLjQxLS40LjUzLTEuMDEuMzItMS41My0uMjItLjUzLS44LS43OS0xLjMxLS44Ny0uOTYuMDEtMjMuNy40OS00My45NiwyMC4xOCwwLDAsMCwwLDAsMGwtMjAuMDcsMTkuNzYtMTkuNTgtMTkuNzZDNjcuMjUuNDksNDQuNTEuMDEsNDMuNTUsMGMtLjU2LjA1LTEuMDkuMzQtMS4zMS44Ny0uMjIuNTMtLjA5LDEuMTQuMzIsMS41M2w1LjY3LDUuNTFjNS4xLjIyLDEwLjE0LjcxLDE0LjQzLDQsLjQyLjMyLjIsMS4xMi0uMzkuOTMtMi41OC0uODYtNi4wMi0uODctOS4zOS0uNGwxNS41NiwxNS4xMmMtMS4xNy0uNS0yLjM2LS45Ny0zLjU0LTEuNDEtMzEuNC0xMS43Mi01Ni4zLTEuNDEtNTcuMzUtLjk2LS41Mi4yMi0uODYuNzUtLjg1LDEuMzJzLjM3LDEuMDguOTEsMS4yOGwxMS4wNiw0LjEzYzQuNDYtMS40OCw4LjctMi4zOSwxMC40Mi0yLjU1LjU3LS4wNS41Ni43My4xMi45MS0xLjg2Ljc0LTMuNjEsMi4yOS01LjI3LDMuNjFsMjUuOTQsOS42OEMxOS4xOCw0NS4xMSwxLjIyLDYxLjg0LjQzLDYyLjU5Yy0uNDEuMzktLjU1LDEtLjM0LDEuNTMuMjEuNTMuNzMuODgsMS4zLjg4aDEzLjljLjE1LS4wOS4zMS0uMTkuNDUtLjI4LDUuNzktMy41OCwxMS45NC02LjE5LDE4LjE4LTguODcuNjgtLjI5LDEuMjguNjQuNiwxLjAzLTMuNTQsMi4wMy02LjU0LDUuMS05LjQ5LDguMTNoMTQuNTljNC4yNy0zLjExLDguODItNS43LDEzLjE2LTguNy41OS0uNDEsMS4yMi40OS43NS45Ny0yLjM1LDIuMzgtNC40NCw1LjA2LTYuNTMsNy43NGgxMTYuODNjLS45OS0zLjE5LTIuMDItNi4zNS00LjEzLTkuMDQtLjMzLS40Mi4xOC0uOTYuNTktLjU5LDMuMzYsMy4wMSw3LjM3LDYuMTUsMTEuMDIsOS42M2gxNS4zNGMtMS4zOC0zLjUyLTMuMDUtNi44Mi01LjcxLTguNjctLjU0LS4zNy0uMDgtMS4xNS41MS0uODcsNC40LDIuMDgsOC4yNyw1Ljg2LDExLjY1LDkuNTRoMjAuMmMuNTcsMCwxLjA5LS4zNSwxLjMtLjg4LjIxLS41My4wOC0xLjE0LS4zNC0xLjUzWiIvPgogICAgICA8L2c+CiAgICAgIDxwYXRoIGNsYXNzPSJjbHMtMSIgZD0ibTEwMS4wNiwyMjEuMzNoMTMuOTd2LTMzLjZoLTEzLjk3djMzLjZaIi8+CiAgICA8L2c+CiAgPC9nPgo8L3N2Zz4=\"\u003e\n  \u003c/a\u003e\n  \u003ca aria-label=\"NPM version\" href=\"https://twitter.com/dimitrikennedy\"\u003e\n    \u003cimg alt=\"llm-polyglot\" src=\"https://img.shields.io/twitter/follow/dimitrikennedy?style=social\u0026labelColor=000000\"\u003e\n  \u003c/a\u003e\n  \u003ca aria-label=\"NPM version\" href=\"https://www.npmjs.com/package/zod-stream\"\u003e\n    \u003cimg alt=\"zod-stream\" src=\"https://img.shields.io/npm/v/zod-stream.svg?style=flat-square\u0026logo=npm\u0026labelColor=000000\u0026label=zod-stream\"\u003e\n  \u003c/a\u003e\n    \u003ca aria-label=\"NPM version\" href=\"https://www.npmjs.com/package/evalz\"\u003e\n    \u003cimg alt=\"evalz\" src=\"https://img.shields.io/npm/v/evalz.svg?style=flat-square\u0026logo=npm\u0026labelColor=000000\u0026label=evalz\"\u003e\n  \u003c/a\u003e\n  \u003ca aria-label=\"NPM version\" href=\"https://www.npmjs.com/package/stream-hooks\"\u003e\n    \u003cimg alt=\"stream-hooks\" src=\"https://img.shields.io/npm/v/stream-hooks.svg?style=flat-square\u0026logo=npm\u0026labelColor=000000\u0026label=stream-hooks\"\u003e\n  \u003c/a\u003e\n  \u003ca aria-label=\"NPM version\" href=\"https://www.npmjs.com/package/schema-stream\"\u003e\n    \u003cimg alt=\"schema-stream\" src=\"https://img.shields.io/npm/v/schema-stream.svg?style=flat-square\u0026logo=npm\u0026labelColor=000000\u0026label=schema-stream\"\u003e\n  \u003c/a\u003e\n  \u003ca aria-label=\"Made by hack.dance\" href=\"https://hack.dance\"\u003e\n    \u003cimg alt=\"docs\" src=\"https://img.shields.io/badge/MADE%20BY%20HACK.DANCE-000000.svg?style=flat-square\u0026labelColor=000000\"\u003e\n  \u003c/a\u003e\n\n\u003c/div\u003e\n\n## Overview\n\nIsland AI is a collection of low-level utilities and high-level tools for handling structured data streams from LLMs. The packages range from basic JSON streaming parsers to complete LLM clients, giving you the flexibility to build custom solutions or use pre-built integrations.\n\n## Core Packages\n\n### 1. schema-stream\n\nA foundational streaming JSON parser that enables immediate data access through structured stubs.\n\n**Key Features:**\n\n- Streaming JSON parser with typed outputs\n- Default value support\n- Path completion tracking\n- Nested object and array support\n\n```typescript\nimport { SchemaStream } from \"schema-stream\";\nimport { z } from \"zod\";\n\n// Define complex nested schemas\nconst schema = z.object({\n  layer1: z.object({\n    layer2: z.object({\n      value: z.string(),\n      layer3: z.object({\n        layer4: z.object({\n          layer5: z.string()\n        })\n      })\n    })\n  }),\n  someArray: z.array(z.object({\n    someString: z.string(),\n    someNumber: z.number()\n  }))\n});\n\n// Get a readable stream of json (from an api or otherwise)\nasync function getSomeStreamOfJson(\n  jsonString: string\n): Promise\u003c{ body: ReadableStream }\u003e {\n  const stream = new ReadableStream({\n    start(controller) {\n      const encoder = new TextEncoder()\n      const jsonBytes = encoder.encode(jsonString)\n\n      for (let i = 0; i \u003c jsonBytes.length; ) {\n        const chunkSize = Math.floor(Math.random() * 5) + 2\n        const chunk = jsonBytes.slice(i, i + chunkSize)\n        controller.enqueue(chunk)\n        i += chunkSize\n      }\n      controller.close()\n    },\n  })\n\n  return { body: stream }\n}\n\n\n// Create parser with completion tracking\nconst parser = new SchemaStream(schema, {\n  onKeyComplete({ completedPaths }) {\n    console.log('Completed paths:', completedPaths);\n  }\n});\n\n// Get the readabale stream to parse\nconst readableStream = await getSomeStreamOfJson(\n  `{\"someString\": \"Hello schema-stream\", \"someNumber\": 42000000}`\n)\n\n// Parse streaming data\nconst stream = parser.parse();\nreadableStream.pipeThrough(stream);\n\n// Get typed results\nconst reader = stream.readable.getReader();\nconst decoder = new TextDecoder()\nlet result = {}\nlet complete = false\n\nwhile (true) {\n  const { value, done } = await reader.read();\n  complete = done\n  \n  if (complete) break;\n  \n  result = JSON.parse(decoder.decode(value));\n  // result is fully typed based on schema\n}\n```\n\n### 2. zod-stream\n\nExtends schema-stream with OpenAI integration and Zod-specific features.\n\n**Key Features:**\n\n- OpenAI completion streaming\n- Multiple response modes (TOOLS, FUNCTIONS, JSON, etc.)\n- Schema validation during streaming\n\n```typescript\nimport { OAIStream } from \"zod-stream\";\nimport { withResponseModel } from \"zod-stream\";\nimport { z } from \"zod\";\n\n// Define extraction schema\nconst ExtractionSchema = z.object({\n  users: z.array(z.object({\n    name: z.string(),\n    handle: z.string(),\n    twitter: z.string()\n  })).min(3),\n  location: z.string(),\n  budget: z.number()\n});\n\n// Configure OpenAI params with schema\nconst params = withResponseModel({\n  response_model: { \n    schema: ExtractionSchema, \n    name: \"Extract\" \n  },\n  params: {\n    messages: [{ role: \"user\", content: textBlock }],\n    model: \"gpt-4\"\n  },\n  mode: \"TOOLS\"\n});\n\n// Stream completions\nconst stream = OAIStream({ \n  res: await oai.chat.completions.create({\n    ...params,\n    stream: true\n  })\n});\n\n// Process results\nconst client = new ZodStream();\nconst extractionStream = await client.create({\n  completionPromise: () =\u003e stream,\n  response_model: { \n    schema: ExtractionSchema, \n    name: \"Extract\" \n  }\n});\n\nfor await (const data of extractionStream) {\n  console.log('Progressive update:', data);\n}\n```\n\n### 3. stream-hooks\n\nReact hooks for consuming streaming JSON data with Zod schema validation.\n\n**Key Features:**\n\n- Ready-to-use React hooks\n- Automatic schema validation\n- Progress tracking\n- Error handling\n\n```typescript\nimport { useJsonStream } from \"stream-hooks\";\n\nfunction DataViewer() {\n  const { loading, startStream, data, error } = useJsonStream({\n    schema: ExtractionSchema,\n    onReceive: (update) =\u003e {\n      console.log('Progressive update:', update);\n    },\n  });\n\n  return (\n    \u003cdiv\u003e\n      {loading \u0026\u0026 \u003cdiv\u003eLoading...\u003c/div\u003e}\n      {error \u0026\u0026 \u003cdiv\u003eError: {error.message}\u003c/div\u003e}\n      {data \u0026\u0026 (\n        \u003cpre\u003e{JSON.stringify(data, null, 2)}\u003c/pre\u003e\n      )}\n      \u003cbutton onClick={() =\u003e startStream({\n        url: \"/api/extract\",\n        method: \"POST\",\n        body: { text: \"...\" }\n      })}\u003e\n        Start Extraction\n      \u003c/button\u003e\n    \u003c/div\u003e\n  );\n}\n```\n\n### 4. evalz\n\nStructured evaluation tools for assessing LLM outputs across multiple dimensions. Built with TypeScript and integrated with OpenAI and Instructor, it enables both automated evaluation and human-in-the-loop assessment workflows.\n\n**Key Features:**\n\n- 🎯 **Model-Graded Evaluation**: Leverage LLMs to assess response quality\n- 📊 **Accuracy Measurement**: Compare outputs using semantic and lexical similarity\n- 🔍 **Context Validation**: Evaluate responses against source materials\n- ⚖️ **Composite Assessment**: Combine multiple evaluation types with custom weights\n\n```typescript\n// Combine different evaluator types\nconst compositeEval = createWeightedEvaluator({\n  evaluators: {\n    entities: createContextEvaluator({ type: \"entities-recall\" }),\n    accuracy: createAccuracyEvaluator({\n      weights: { \n        factual: 0.9,   // High weight on exact matches\n        semantic: 0.1    // Low weight on similar terms\n      }\n    }),\n    quality: createEvaluator({\n      client: oai,\n      model: \"gpt-4-turbo\",\n      evaluationDescription: \"Rate quality\"\n    })\n  },\n  weights: {\n    entities: 0.3,\n    accuracy: 0.4,\n    quality: 0.3\n  }\n});\n\n// Must provide all required fields for each evaluator type\nawait compositeEval({\n  data: [{\n    prompt: \"Summarize the earnings call\",\n    completion: \"CEO Jane Smith announced 15% growth\",\n    expectedCompletion: \"The CEO reported strong growth\",\n    groundTruth: \"CEO discussed Q3 performance\",\n    contexts: [\n      \"CEO Jane Smith presented Q3 results\",\n      \"Company saw 15% growth in Q3 2023\"\n    ]\n  }]\n});\n```\n\n### 5. llm-polyglot\n\nA universal LLM client that extends the OpenAI SDK to provide consistent interfaces across different providers that may not follow the OpenAI API specification.\n\n**Native API Support Status:**\n\n| Provider API | Status | Chat | Basic Stream | Functions/Tool calling | Function streaming | Notes |\n|-------------|---------|------|--------------|---------------------|-----------------|--------|\n| OpenAI | ✅ | ✅ | ✅ | ✅ | ✅ | Direct SDK proxy |\n| Anthropic | ✅ | ✅ | ✅ | ❌ | ❌ | Claude models |\n| Google | ✅ | ✅ | ✅ | ✅ | ❌ | Gemini models + context caching |\n| Azure | 🚧 | ✅ | ✅ | ❌ | ❌ | OpenAI model hosting |\n| Cohere | ❌ | - | - | - | - | Not supported |\n| AI21 | ❌ | - | - | - | - | Not supported |\n\nStream Types:\n\n- **Basic Stream**: Simple text streaming\n- **Partial JSON Stream**: Progressive JSON object construction during streaming\n- **Function Stream**: Streaming function/tool calls and their results\n\n\u003cbr /\u003e\n\n**OpenAI-Compatible Hosting Providers:**\n\nThese providers use the OpenAI SDK format, so they work directly with the OpenAI client configuration:\n\n| Provider | How to Use | Available Models |\n|----------|------------|------------------|\n| Together | Use OpenAI client with Together base URL | Mixtral, Llama, OpenChat, Yi, others |\n| Anyscale | Use OpenAI client with Anyscale base URL | Mistral, Llama, others |\n| Perplexity | Use OpenAI client with Perplexity base URL | pplx-* models |\n| Replicate | Use OpenAI client with Replicate base URL | Various open models |\n\n**Key Features:**\n\n- OpenAI-compatible interface for non-OpenAI providers\n- Support for major providers:\n  - OpenAI (direct SDK proxy)\n  - Anthropic (Claude models)\n  - Google (Gemini models)\n  - Together\n  - Microsoft/Azure\n  - Anyscale\n- Streaming support across providers\n- Function/tool calling compatibility\n- Context caching for Gemini\n- Structured output support\n\n#### Basic OpenAI-Style Usage\n\n```typescript\nimport { createLLMClient } from \"llm-polyglot\";\n\n// Create provider-specific client\nconst anthropicClient = createLLMClient({\n  provider: \"anthropic\"\n});\n\n// Use consistent OpenAI-style API\nconst completion = await anthropicClient.chat.completions.create({\n  model: \"claude-3-opus-20240229\",\n  max_tokens: 1000,\n  messages: [{ role: \"user\", content: \"Extract data...\" }]\n});\n```\n\n#### Streaming with Different Providers\n\n```typescript\n// Anthropic Streaming\nconst stream = await anthropicClient.chat.completions.create({\n  model: \"claude-3-opus-20240229\",\n  max_tokens: 1000,\n  stream: true,\n  messages: [{ role: \"user\", content: \"Stream some content...\" }]\n});\n\nlet content = \"\";\nfor await (const chunk of stream) {\n  content += chunk.choices?.[0]?.delta?.content ?? \"\";\n}\n\n// Google/Gemini with Context Caching\nconst googleClient = createLLMClient({\n  provider: \"google\"\n});\n\n// Create a context cache\nconst cache = await googleClient.cacheManager.create({\n  model: \"gemini-1.5-flash-8b\",\n  messages: [{ \n    role: \"user\", \n    content: \"What is the capital of Montana?\" \n  }],\n  ttlSeconds: 3600, // Cache for 1 hour\n  max_tokens: 1000\n});\n\n// Use cached context in new completion\nconst completion = await googleClient.chat.completions.create({\n  model: \"gemini-1.5-flash-8b\",\n  messages: [{ \n    role: \"user\", \n    content: \"What state is it in?\" \n  }],\n  additionalProperties: {\n    cacheName: cache.name\n  },\n  max_tokens: 1000\n});\n```\n\n#### Function/Tool Calling\n\n```typescript\nconst completion = await anthropicClient.chat.completions.create({\n  model: \"claude-3-opus-20240229\",\n  max_tokens: 1000,\n  messages: [{ \n    role: \"user\", \n    content: \"Extract user information...\" \n  }],\n  tool_choice: {\n    type: \"function\",\n    function: { name: \"extract_user\" }\n  },\n  tools: [{\n    type: \"function\",\n    function: {\n      name: \"extract_user\",\n      description: \"Extract user information\",\n      parameters: {\n        type: \"object\",\n        properties: {\n          name: { type: \"string\" },\n          age: { type: \"number\" }\n        },\n        required: [\"name\", \"age\"]\n      }\n    }\n  }]\n});\n```\n\n// Using with OpenAI-compatible providers:\n\n```typescript\nconst client = createLLMClient({\n  provider: \"openai\",\n  apiKey: \"your_api_key\",\n  baseURL: \"https://api.together.xyz/v1\",  // or other provider URLs\n});\n```\n\n#### Provider-Specific Features\n\n1. **Anthropic (Claude)**\n   - Full function/tool calling support\n   - Message streaming\n   - OpenAI-compatible responses\n\n2. **Google (Gemini)**\n   - Context caching for token optimization\n   - Streaming support\n   - Function calling\n   - Optional OpenAI compatibility mode\n   - Grounding (i.e. Google Search) support\n\n3. **OpenAI**\n   - Direct SDK proxy\n   - All native OpenAI features supported\n\n## zod-stream/schema-stream vs Instructor\n\nThe core Island AI packages provides more low-level utilities for building custom LLM clients and data handling pipelines (schema-stream, zod-stream, stream-hooks). For a complete, ready-to-use solution, check out [Instructor](https://github.com/instructor-ai/instructor-js), which composes some of these tools into a full-featured client.\n\n**When to use core packages:**\n\n- You need direct access to the HTTP stream for custom transport (e.g., not using SSE/WebSockets)\n- You want to build a custom LLM client\n- You need fine-grained control over streaming and parsing\n- You're implementing server-side streaming with client-side parsing\n- You need a structured evaluation tool\n- You want to use different LLM providers that don't support the OpenAI SDK format\n\n**When to use Instructor:**\n\n- You want a complete solution for structured extraction\n- You're using WebSocket-based streaming from server to client\n- You're requests are only on the server\n- You need the full async generator pattern for progressive object updates\n- You want OpenAI SDK compatibility out of the box\n\n## Transport Patterns\n\n### Direct HTTP Streaming\n\nFor cases where you need direct control over the HTTP stream, you can use the core packages to build your own streaming endpoints:\n\n```typescript\nimport { OAIStream } from \"zod-stream\";\nimport { withResponseModel } from \"zod-stream\";\nimport OpenAI from \"openai\";\nimport { z } from \"zod\";\n\nconst oai = new OpenAI({\n  apiKey: process.env.OPENAI_API_KEY,\n  organization: process.env.OPENAI_ORG_ID\n});\n\n// Define your schema\nconst schema = z.object({\n  content: z.string(),\n  users: z.array(z.object({\n    name: z.string(),\n  })),\n});\n\n// API Route Example (Next.js)\nexport async function POST(request: Request) {\n  const { messages } = await request.json();\n\n  // Configure OpenAI parameters with schema\n  const params = withResponseModel({\n    response_model: { \n      schema: schema, \n      name: \"Users extraction and message\" \n    },\n    params: {\n      messages,\n      model: \"gpt-4\",\n    },\n    mode: \"TOOLS\",\n  });\n\n  // Create streaming completion\n  const extractionStream = await oai.chat.completions.create({\n    ...params,\n    stream: true,\n  });\n\n  // Return streaming response\n  return new Response(\n    OAIStream({ res: extractionStream })\n  );\n}\n\n// Client-side consumption\nasync function consumeStream() {\n  const response = await fetch('/api/extract', {\n    method: 'POST',\n    body: JSON.stringify({\n      messages: [{ role: 'user', content: 'Your prompt here' }]\n    })\n  });\n\n  const parser = new SchemaStream(schema);\n  const stream = parser.parse();\n\n  response.body\n    ?.pipeThrough(stream)\n    .pipeTo(new WritableStream({\n      write(chunk) {\n        const data = JSON.parse(new TextDecoder().decode(chunk));\n        // Use partial data as it arrives\n        console.log('Partial data:', data);\n      }\n    }));\n}\n```\n\n### Using Instructor\n\n  \u003ca aria-label=\"NPM version\" href=\"https://www.npmjs.com/package/@instructor-ai/instructor\" target=\"_blank\"\u003e\n    \u003cimg alt=\"schema-stream\" src=\"https://img.shields.io/npm/v/@instructor-ai/instructor.svg?style=flat-square\u0026logo=npm\u0026labelColor=000000\u0026label=@instructor-ai/instructor\"\u003e\n  \u003c/a\u003e\n  \u003ca aria-label=\"Github Repo\" href=\"https://github.com/instructor-ai/instructor-js\" target=\"_blank\"\u003e\n    \u003cimg alt=\"instructor-js\" src=\"https://img.shields.io/github/stars/instructor-ai/instructor-js?style=flat-square\u0026logo=github\u0026labelColor=000000\u0026label=instructor-ai/instructor-js\"\u003e\n  \u003c/a\u003e\n\n[Instructor](https://github.com/instructor-ai/instructor-js) provides a high-level client that composes Island AI's core packages into a complete solution for structured extraction. It extends the OpenAI client with streaming and schema validation capabilities.\n\n```typescript\nimport Instructor from \"@instructor-ai/instructor\";\nimport OpenAI from \"openai\";\nimport { z } from \"zod\";\n\n// Define your extraction schema\nconst ExtractionSchema = z.object({\n  users: z.array(\n    z.object({\n      name: z.string(),\n      handle: z.string(),\n      twitter: z.string()\n    })\n  ).min(3),\n  location: z.string(),\n  budget: z.number()\n});\n\ntype Extraction = Partial\u003cz.infer\u003ctypeof ExtractionSchema\u003e\u003e;\n\n// Initialize OpenAI client with Instructor\nconst oai = new OpenAI({\n  apiKey: process.env.OPENAI_API_KEY,\n  organization: process.env.OPENAI_ORG_ID\n});\n\nconst client = Instructor({\n  client: oai,\n  mode: \"TOOLS\"\n});\n\n// Stream completions with structured output\nconst extractionStream = await client.chat.completions.create({\n  messages: [{ \n    role: \"user\", \n    content: \"Your text content here...\" \n  }],\n  model: \"gpt-4\",\n  response_model: { \n    schema: ExtractionSchema, \n    name: \"Extract\" \n  },\n  max_retries: 3,\n  stream: true,\n  stream_options: {\n    include_usage: true\n  }\n});\n\n// Process streaming results\nlet extraction: Extraction = {};\nfor await (const result of extractionStream) {\n  extraction = result;\n  console.log('Progressive update:', result);\n}\n\nconsole.log('Final extraction:', extraction);\n```\n\n## Key Differences\n\n1. **Instructor**\n   - Provides a complete solution built on top of the OpenAI SDK\n   - Handles retries, validation, and streaming automatically\n   - Returns an async generator for progressive updates\n   - Ideal for WebSocket-based streaming from server to client\n   - Simpler integration when you don't need low-level control\n\n2. **Direct HTTP Streaming**\n   - Gives you direct access to the HTTP stream\n   - Allows custom transport mechanisms\n   - Enables server-side streaming with client-side parsing\n   - More flexible for custom implementations\n   - Better for scenarios where you need to minimize server processing\n\n## Contributing\n\nWe welcome contributions! Check out our issues labeled as `good-first-issue` or `help-wanted`.\n\n## Documentation\n\nFor detailed documentation, visit [https://island.hack.dance](https://island.hack.dance)\n\n## License\n\nMIT License - see LICENSE file for details.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhack-dance%2Fisland-ai","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhack-dance%2Fisland-ai","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhack-dance%2Fisland-ai/lists"}