@jcheesepkg/nanobot 0.9.1 → 0.9.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +18 -18
- package/dist/agent/context.d.mts +4 -4
- package/dist/agent/context.d.mts.map +1 -1
- package/dist/agent/context.mjs +27 -28
- package/dist/agent/context.mjs.map +1 -1
- package/dist/agent/loop.d.mts +5 -3
- package/dist/agent/loop.d.mts.map +1 -1
- package/dist/agent/loop.mjs +64 -55
- package/dist/agent/loop.mjs.map +1 -1
- package/dist/agent/memory.d.mts.map +1 -1
- package/dist/agent/memory.mjs +3 -3
- package/dist/agent/memory.mjs.map +1 -1
- package/dist/agent/skills.d.mts.map +1 -1
- package/dist/agent/skills.mjs +4 -4
- package/dist/agent/skills.mjs.map +1 -1
- package/dist/agent/subagent.d.mts.map +1 -1
- package/dist/agent/subagent.mjs +22 -22
- package/dist/agent/subagent.mjs.map +1 -1
- package/dist/agent/tools/base.mjs +2 -2
- package/dist/agent/tools/base.mjs.map +1 -1
- package/dist/agent/tools/cron.d.mts +1 -1
- package/dist/agent/tools/cron.d.mts.map +1 -1
- package/dist/agent/tools/cron.mjs +11 -11
- package/dist/agent/tools/cron.mjs.map +1 -1
- package/dist/agent/tools/filesystem.d.mts +4 -4
- package/dist/agent/tools/filesystem.d.mts.map +1 -1
- package/dist/agent/tools/filesystem.mjs +20 -20
- package/dist/agent/tools/filesystem.mjs.map +1 -1
- package/dist/agent/tools/flex.d.mts +1 -1
- package/dist/agent/tools/flex.d.mts.map +1 -1
- package/dist/agent/tools/flex.mjs +112 -112
- package/dist/agent/tools/flex.mjs.map +1 -1
- package/dist/agent/tools/flex.test.mjs +60 -59
- package/dist/agent/tools/flex.test.mjs.map +1 -1
- package/dist/agent/tools/message.d.mts +1 -1
- package/dist/agent/tools/message.d.mts.map +1 -1
- package/dist/agent/tools/message.mjs +4 -4
- package/dist/agent/tools/message.mjs.map +1 -1
- package/dist/agent/tools/registry.d.mts.map +1 -1
- package/dist/agent/tools/registry.mjs +4 -4
- package/dist/agent/tools/registry.mjs.map +1 -1
- package/dist/agent/tools/shell.d.mts +1 -1
- package/dist/agent/tools/shell.mjs +4 -4
- package/dist/agent/tools/shell.mjs.map +1 -1
- package/dist/agent/tools/spawn.d.mts +1 -1
- package/dist/agent/tools/spawn.d.mts.map +1 -1
- package/dist/agent/tools/spawn.mjs +4 -4
- package/dist/agent/tools/spawn.mjs.map +1 -1
- package/dist/agent/tools/web.d.mts +2 -2
- package/dist/agent/tools/web.d.mts.map +1 -1
- package/dist/agent/tools/web.mjs +36 -36
- package/dist/agent/tools/web.mjs.map +1 -1
- package/dist/bus/events.mjs +1 -1
- package/dist/bus/events.mjs.map +1 -1
- package/dist/bus/queue.d.mts.map +1 -1
- package/dist/bus/queue.mjs.map +1 -1
- package/dist/channels/base.d.mts.map +1 -1
- package/dist/channels/base.mjs +2 -2
- package/dist/channels/base.mjs.map +1 -1
- package/dist/channels/line.d.mts +1 -0
- package/dist/channels/line.d.mts.map +1 -1
- package/dist/channels/line.mjs +65 -65
- package/dist/channels/line.mjs.map +1 -1
- package/dist/channels/line.test.mjs +26 -27
- package/dist/channels/line.test.mjs.map +1 -1
- package/dist/channels/manager.d.mts.map +1 -1
- package/dist/channels/manager.mjs +9 -9
- package/dist/channels/manager.mjs.map +1 -1
- package/dist/channels/telegram.mjs +34 -34
- package/dist/channels/telegram.mjs.map +1 -1
- package/dist/cli/index.mjs +36 -36
- package/dist/cli/index.mjs.map +1 -1
- package/dist/config/loader.d.mts.map +1 -1
- package/dist/config/loader.mjs +1 -1
- package/dist/config/loader.mjs.map +1 -1
- package/dist/config/schema.d.mts +387 -387
- package/dist/config/schema.d.mts.map +1 -1
- package/dist/config/schema.mjs +42 -42
- package/dist/config/schema.mjs.map +1 -1
- package/dist/gateway/server.d.mts.map +1 -1
- package/dist/gateway/server.mjs +48 -54
- package/dist/gateway/server.mjs.map +1 -1
- package/dist/heartbeat/service.d.mts.map +1 -1
- package/dist/heartbeat/service.mjs +8 -8
- package/dist/heartbeat/service.mjs.map +1 -1
- package/dist/index.d.mts +1 -1
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +2 -2
- package/dist/index.mjs.map +1 -1
- package/dist/node_modules/{@jridgewell → .bun/@jridgewell_sourcemap-codec@1.5.5/node_modules/@jridgewell}/sourcemap-codec/dist/sourcemap-codec.mjs +1 -1
- package/dist/node_modules/.bun/@jridgewell_sourcemap-codec@1.5.5/node_modules/@jridgewell/sourcemap-codec/dist/sourcemap-codec.mjs.map +1 -0
- package/dist/node_modules/{@vitest → .bun/@vitest_expect@2.1.9/node_modules/@vitest}/expect/dist/index.mjs +8 -8
- package/dist/node_modules/.bun/@vitest_expect@2.1.9/node_modules/@vitest/expect/dist/index.mjs.map +1 -0
- package/dist/node_modules/{@vitest → .bun/@vitest_pretty-format@2.1.9/node_modules/@vitest}/pretty-format/dist/index.mjs +2 -2
- package/dist/node_modules/.bun/@vitest_pretty-format@2.1.9/node_modules/@vitest/pretty-format/dist/index.mjs.map +1 -0
- package/dist/node_modules/{@vitest → .bun/@vitest_runner@2.1.9/node_modules/@vitest}/runner/dist/chunk-tasks.mjs +1 -1
- package/dist/node_modules/.bun/@vitest_runner@2.1.9/node_modules/@vitest/runner/dist/chunk-tasks.mjs.map +1 -0
- package/dist/node_modules/{@vitest → .bun/@vitest_runner@2.1.9/node_modules/@vitest}/runner/dist/index.mjs +6 -6
- package/dist/node_modules/.bun/@vitest_runner@2.1.9/node_modules/@vitest/runner/dist/index.mjs.map +1 -0
- package/dist/node_modules/{@vitest → .bun/@vitest_snapshot@2.1.9/node_modules/@vitest}/snapshot/dist/index.mjs +5 -5
- package/dist/node_modules/.bun/@vitest_snapshot@2.1.9/node_modules/@vitest/snapshot/dist/index.mjs.map +1 -0
- package/dist/node_modules/{@vitest → .bun/@vitest_spy@2.1.9/node_modules/@vitest}/spy/dist/index.mjs +2 -2
- package/dist/node_modules/.bun/@vitest_spy@2.1.9/node_modules/@vitest/spy/dist/index.mjs.map +1 -0
- package/dist/node_modules/{@vitest → .bun/@vitest_utils@2.1.9/node_modules/@vitest}/utils/dist/chunk-_commonjsHelpers.mjs +3 -3
- package/dist/node_modules/.bun/@vitest_utils@2.1.9/node_modules/@vitest/utils/dist/chunk-_commonjsHelpers.mjs.map +1 -0
- package/dist/node_modules/{@vitest → .bun/@vitest_utils@2.1.9/node_modules/@vitest}/utils/dist/diff.mjs +4 -4
- package/dist/node_modules/.bun/@vitest_utils@2.1.9/node_modules/@vitest/utils/dist/diff.mjs.map +1 -0
- package/dist/node_modules/{@vitest → .bun/@vitest_utils@2.1.9/node_modules/@vitest}/utils/dist/error.mjs +3 -3
- package/dist/node_modules/.bun/@vitest_utils@2.1.9/node_modules/@vitest/utils/dist/error.mjs.map +1 -0
- package/dist/node_modules/{@vitest → .bun/@vitest_utils@2.1.9/node_modules/@vitest}/utils/dist/helpers.mjs +1 -1
- package/dist/node_modules/.bun/@vitest_utils@2.1.9/node_modules/@vitest/utils/dist/helpers.mjs.map +1 -0
- package/dist/node_modules/{@vitest → .bun/@vitest_utils@2.1.9/node_modules/@vitest}/utils/dist/index.mjs +3 -3
- package/dist/node_modules/.bun/@vitest_utils@2.1.9/node_modules/@vitest/utils/dist/index.mjs.map +1 -0
- package/dist/node_modules/{@vitest → .bun/@vitest_utils@2.1.9/node_modules/@vitest}/utils/dist/source-map.mjs +1 -1
- package/dist/node_modules/.bun/@vitest_utils@2.1.9/node_modules/@vitest/utils/dist/source-map.mjs.map +1 -0
- package/dist/node_modules/{chai → .bun/chai@5.3.3/node_modules/chai}/index.mjs +1 -1
- package/dist/node_modules/.bun/chai@5.3.3/node_modules/chai/index.mjs.map +1 -0
- package/dist/node_modules/{loupe → .bun/loupe@3.2.1/node_modules/loupe}/lib/arguments.mjs +1 -1
- package/dist/node_modules/.bun/loupe@3.2.1/node_modules/loupe/lib/arguments.mjs.map +1 -0
- package/dist/node_modules/{loupe → .bun/loupe@3.2.1/node_modules/loupe}/lib/array.mjs +1 -1
- package/dist/node_modules/.bun/loupe@3.2.1/node_modules/loupe/lib/array.mjs.map +1 -0
- package/dist/node_modules/{loupe → .bun/loupe@3.2.1/node_modules/loupe}/lib/bigint.mjs +1 -1
- package/dist/node_modules/.bun/loupe@3.2.1/node_modules/loupe/lib/bigint.mjs.map +1 -0
- package/dist/node_modules/{loupe → .bun/loupe@3.2.1/node_modules/loupe}/lib/class.mjs +1 -1
- package/dist/node_modules/.bun/loupe@3.2.1/node_modules/loupe/lib/class.mjs.map +1 -0
- package/dist/node_modules/{loupe → .bun/loupe@3.2.1/node_modules/loupe}/lib/date.mjs +1 -1
- package/dist/node_modules/.bun/loupe@3.2.1/node_modules/loupe/lib/date.mjs.map +1 -0
- package/dist/node_modules/{loupe → .bun/loupe@3.2.1/node_modules/loupe}/lib/error.mjs +1 -1
- package/dist/node_modules/.bun/loupe@3.2.1/node_modules/loupe/lib/error.mjs.map +1 -0
- package/dist/node_modules/{loupe → .bun/loupe@3.2.1/node_modules/loupe}/lib/function.mjs +1 -1
- package/dist/node_modules/.bun/loupe@3.2.1/node_modules/loupe/lib/function.mjs.map +1 -0
- package/dist/node_modules/{loupe → .bun/loupe@3.2.1/node_modules/loupe}/lib/helpers.mjs +1 -1
- package/dist/node_modules/.bun/loupe@3.2.1/node_modules/loupe/lib/helpers.mjs.map +1 -0
- package/dist/node_modules/{loupe → .bun/loupe@3.2.1/node_modules/loupe}/lib/html.mjs +1 -1
- package/dist/node_modules/.bun/loupe@3.2.1/node_modules/loupe/lib/html.mjs.map +1 -0
- package/dist/node_modules/{loupe → .bun/loupe@3.2.1/node_modules/loupe}/lib/index.mjs +1 -1
- package/dist/node_modules/.bun/loupe@3.2.1/node_modules/loupe/lib/index.mjs.map +1 -0
- package/dist/node_modules/{loupe → .bun/loupe@3.2.1/node_modules/loupe}/lib/map.mjs +1 -1
- package/dist/node_modules/.bun/loupe@3.2.1/node_modules/loupe/lib/map.mjs.map +1 -0
- package/dist/node_modules/{loupe → .bun/loupe@3.2.1/node_modules/loupe}/lib/number.mjs +1 -1
- package/dist/node_modules/.bun/loupe@3.2.1/node_modules/loupe/lib/number.mjs.map +1 -0
- package/dist/node_modules/{loupe → .bun/loupe@3.2.1/node_modules/loupe}/lib/object.mjs +1 -1
- package/dist/node_modules/.bun/loupe@3.2.1/node_modules/loupe/lib/object.mjs.map +1 -0
- package/dist/node_modules/.bun/loupe@3.2.1/node_modules/loupe/lib/promise.mjs +6 -0
- package/dist/node_modules/.bun/loupe@3.2.1/node_modules/loupe/lib/promise.mjs.map +1 -0
- package/dist/node_modules/{loupe → .bun/loupe@3.2.1/node_modules/loupe}/lib/regexp.mjs +1 -1
- package/dist/node_modules/.bun/loupe@3.2.1/node_modules/loupe/lib/regexp.mjs.map +1 -0
- package/dist/node_modules/{loupe → .bun/loupe@3.2.1/node_modules/loupe}/lib/set.mjs +1 -1
- package/dist/node_modules/.bun/loupe@3.2.1/node_modules/loupe/lib/set.mjs.map +1 -0
- package/dist/node_modules/{loupe → .bun/loupe@3.2.1/node_modules/loupe}/lib/string.mjs +1 -1
- package/dist/node_modules/.bun/loupe@3.2.1/node_modules/loupe/lib/string.mjs.map +1 -0
- package/dist/node_modules/{loupe → .bun/loupe@3.2.1/node_modules/loupe}/lib/symbol.mjs +1 -1
- package/dist/node_modules/.bun/loupe@3.2.1/node_modules/loupe/lib/symbol.mjs.map +1 -0
- package/dist/node_modules/{loupe → .bun/loupe@3.2.1/node_modules/loupe}/lib/typedarray.mjs +1 -1
- package/dist/node_modules/.bun/loupe@3.2.1/node_modules/loupe/lib/typedarray.mjs.map +1 -0
- package/dist/node_modules/{magic-string → .bun/magic-string@0.30.21/node_modules/magic-string}/dist/magic-string.es.mjs +2 -2
- package/dist/node_modules/.bun/magic-string@0.30.21/node_modules/magic-string/dist/magic-string.es.mjs.map +1 -0
- package/dist/node_modules/{@vitest/snapshot → .bun/pathe@1.1.2}/node_modules/pathe/dist/shared/pathe.ff20891b.mjs +1 -1
- package/dist/node_modules/.bun/pathe@1.1.2/node_modules/pathe/dist/shared/pathe.ff20891b.mjs.map +1 -0
- package/dist/node_modules/{tinyrainbow → .bun/tinyrainbow@1.2.0/node_modules/tinyrainbow}/dist/chunk-BVHSVHOK.mjs +1 -1
- package/dist/node_modules/.bun/tinyrainbow@1.2.0/node_modules/tinyrainbow/dist/chunk-BVHSVHOK.mjs.map +1 -0
- package/dist/node_modules/{tinyrainbow → .bun/tinyrainbow@1.2.0/node_modules/tinyrainbow}/dist/node.mjs +1 -1
- package/dist/node_modules/.bun/tinyrainbow@1.2.0/node_modules/tinyrainbow/dist/node.mjs.map +1 -0
- package/dist/node_modules/{tinyspy → .bun/tinyspy@3.0.2/node_modules/tinyspy}/dist/index.mjs +1 -1
- package/dist/node_modules/.bun/tinyspy@3.0.2/node_modules/tinyspy/dist/index.mjs.map +1 -0
- package/dist/node_modules/{vitest → .bun/vitest@2.1.9_7700f9e9ace41f23/node_modules/vitest}/dist/chunks/_commonjsHelpers.BFTU3MAI.mjs +1 -1
- package/dist/node_modules/.bun/vitest@2.1.9_7700f9e9ace41f23/node_modules/vitest/dist/chunks/_commonjsHelpers.BFTU3MAI.mjs.map +1 -0
- package/dist/node_modules/{vitest → .bun/vitest@2.1.9_7700f9e9ace41f23/node_modules/vitest}/dist/chunks/date.W2xKR2qe.mjs +1 -1
- package/dist/node_modules/.bun/vitest@2.1.9_7700f9e9ace41f23/node_modules/vitest/dist/chunks/date.W2xKR2qe.mjs.map +1 -0
- package/dist/node_modules/{vitest → .bun/vitest@2.1.9_7700f9e9ace41f23/node_modules/vitest}/dist/chunks/utils.C8RiOc4B.mjs +2 -2
- package/dist/node_modules/.bun/vitest@2.1.9_7700f9e9ace41f23/node_modules/vitest/dist/chunks/utils.C8RiOc4B.mjs.map +1 -0
- package/dist/node_modules/{vitest → .bun/vitest@2.1.9_7700f9e9ace41f23/node_modules/vitest}/dist/chunks/vi.DgezovHB.mjs +11 -11
- package/dist/node_modules/.bun/vitest@2.1.9_7700f9e9ace41f23/node_modules/vitest/dist/chunks/vi.DgezovHB.mjs.map +1 -0
- package/dist/providers/base.d.mts +2 -2
- package/dist/providers/base.d.mts.map +1 -1
- package/dist/providers/openai-provider.d.mts.map +1 -1
- package/dist/providers/openai-provider.mjs +10 -9
- package/dist/providers/openai-provider.mjs.map +1 -1
- package/dist/providers/registry.d.mts +1 -1
- package/dist/providers/registry.d.mts.map +1 -1
- package/dist/providers/registry.mjs +99 -99
- package/dist/providers/registry.mjs.map +1 -1
- package/dist/session/manager.d.mts +2 -2
- package/dist/session/manager.d.mts.map +1 -1
- package/dist/session/manager.mjs +18 -19
- package/dist/session/manager.mjs.map +1 -1
- package/dist/utils/helpers.d.mts.map +1 -1
- package/dist/utils/helpers.mjs.map +1 -1
- package/package.json +11 -11
- package/skills/cron/SKILL.md +12 -8
- package/skills/daily-summary/SKILL.md +4 -0
- package/skills/english/SKILL.md +21 -7
- package/skills/expense/SKILL.md +11 -7
- package/skills/fortune/SKILL.md +24 -20
- package/skills/habit/SKILL.md +2 -1
- package/skills/hydration/SKILL.md +3 -0
- package/skills/memory/SKILL.md +1 -0
- package/skills/mood/SKILL.md +10 -6
- package/skills/skill-creator/SKILL.md +3 -0
- package/skills/summarize/SKILL.md +1 -0
- package/skills/weather/SKILL.md +10 -8
- package/dist/node_modules/@jridgewell/sourcemap-codec/dist/sourcemap-codec.mjs.map +0 -1
- package/dist/node_modules/@vitest/expect/dist/index.mjs.map +0 -1
- package/dist/node_modules/@vitest/pretty-format/dist/index.mjs.map +0 -1
- package/dist/node_modules/@vitest/runner/dist/chunk-tasks.mjs.map +0 -1
- package/dist/node_modules/@vitest/runner/dist/index.mjs.map +0 -1
- package/dist/node_modules/@vitest/snapshot/dist/index.mjs.map +0 -1
- package/dist/node_modules/@vitest/snapshot/node_modules/pathe/dist/shared/pathe.ff20891b.mjs.map +0 -1
- package/dist/node_modules/@vitest/spy/dist/index.mjs.map +0 -1
- package/dist/node_modules/@vitest/utils/dist/chunk-_commonjsHelpers.mjs.map +0 -1
- package/dist/node_modules/@vitest/utils/dist/diff.mjs.map +0 -1
- package/dist/node_modules/@vitest/utils/dist/error.mjs.map +0 -1
- package/dist/node_modules/@vitest/utils/dist/helpers.mjs.map +0 -1
- package/dist/node_modules/@vitest/utils/dist/index.mjs.map +0 -1
- package/dist/node_modules/@vitest/utils/dist/source-map.mjs.map +0 -1
- package/dist/node_modules/chai/index.mjs.map +0 -1
- package/dist/node_modules/loupe/lib/arguments.mjs.map +0 -1
- package/dist/node_modules/loupe/lib/array.mjs.map +0 -1
- package/dist/node_modules/loupe/lib/bigint.mjs.map +0 -1
- package/dist/node_modules/loupe/lib/class.mjs.map +0 -1
- package/dist/node_modules/loupe/lib/date.mjs.map +0 -1
- package/dist/node_modules/loupe/lib/error.mjs.map +0 -1
- package/dist/node_modules/loupe/lib/function.mjs.map +0 -1
- package/dist/node_modules/loupe/lib/helpers.mjs.map +0 -1
- package/dist/node_modules/loupe/lib/html.mjs.map +0 -1
- package/dist/node_modules/loupe/lib/index.mjs.map +0 -1
- package/dist/node_modules/loupe/lib/map.mjs.map +0 -1
- package/dist/node_modules/loupe/lib/number.mjs.map +0 -1
- package/dist/node_modules/loupe/lib/object.mjs.map +0 -1
- package/dist/node_modules/loupe/lib/promise.mjs +0 -6
- package/dist/node_modules/loupe/lib/promise.mjs.map +0 -1
- package/dist/node_modules/loupe/lib/regexp.mjs.map +0 -1
- package/dist/node_modules/loupe/lib/set.mjs.map +0 -1
- package/dist/node_modules/loupe/lib/string.mjs.map +0 -1
- package/dist/node_modules/loupe/lib/symbol.mjs.map +0 -1
- package/dist/node_modules/loupe/lib/typedarray.mjs.map +0 -1
- package/dist/node_modules/magic-string/dist/magic-string.es.mjs.map +0 -1
- package/dist/node_modules/tinyrainbow/dist/chunk-BVHSVHOK.mjs.map +0 -1
- package/dist/node_modules/tinyrainbow/dist/node.mjs.map +0 -1
- package/dist/node_modules/tinyspy/dist/index.mjs.map +0 -1
- package/dist/node_modules/vitest/dist/chunks/_commonjsHelpers.BFTU3MAI.mjs.map +0 -1
- package/dist/node_modules/vitest/dist/chunks/date.W2xKR2qe.mjs.map +0 -1
- package/dist/node_modules/vitest/dist/chunks/utils.C8RiOc4B.mjs.map +0 -1
- package/dist/node_modules/vitest/dist/chunks/vi.DgezovHB.mjs.map +0 -1
- /package/dist/node_modules/{@vitest → .bun/@vitest_runner@2.1.9/node_modules/@vitest}/runner/dist/utils.mjs +0 -0
|
@@ -12,7 +12,6 @@ var FlexTool = class extends Tool {
|
|
|
12
12
|
name = "flex_message";
|
|
13
13
|
description = "Build a LINE Flex Message from a template. Returns JSON that will be rendered as a rich card in LINE. Use this instead of outputting raw JSON.";
|
|
14
14
|
parameters = {
|
|
15
|
-
type: "object",
|
|
16
15
|
properties: {
|
|
17
16
|
template: {
|
|
18
17
|
type: "string",
|
|
@@ -145,7 +144,8 @@ var FlexTool = class extends Tool {
|
|
|
145
144
|
}
|
|
146
145
|
}
|
|
147
146
|
},
|
|
148
|
-
required: ["template", "data"]
|
|
147
|
+
required: ["template", "data"],
|
|
148
|
+
type: "object"
|
|
149
149
|
};
|
|
150
150
|
async execute(args) {
|
|
151
151
|
const template = String(args.template);
|
|
@@ -177,8 +177,8 @@ var FlexTool = class extends Tool {
|
|
|
177
177
|
default: return `Error: unknown template '${template}'. Use: fortune, info_card, action_buttons, receipt, morning_summary, hydration, custom.`;
|
|
178
178
|
}
|
|
179
179
|
return `${JSON.stringify(flex)}\n\n(Card sent automatically. Do NOT repeat the JSON. Just respond naturally.)`;
|
|
180
|
-
} catch (
|
|
181
|
-
return `Error building flex message: ${
|
|
180
|
+
} catch (error) {
|
|
181
|
+
return `Error building flex message: ${error instanceof Error ? error.message : error}`;
|
|
182
182
|
}
|
|
183
183
|
}
|
|
184
184
|
buildFortune(data) {
|
|
@@ -190,38 +190,35 @@ var FlexTool = class extends Tool {
|
|
|
190
190
|
const starText = "★".repeat(stars) + "☆".repeat(5 - stars);
|
|
191
191
|
const contents = [
|
|
192
192
|
{
|
|
193
|
-
|
|
193
|
+
size: "xl",
|
|
194
194
|
text: sign,
|
|
195
|
-
|
|
196
|
-
|
|
195
|
+
type: "text",
|
|
196
|
+
weight: "bold"
|
|
197
197
|
},
|
|
198
198
|
{
|
|
199
|
-
|
|
200
|
-
text: "今日の運勢",
|
|
199
|
+
color: "#666666",
|
|
201
200
|
size: "sm",
|
|
202
|
-
|
|
201
|
+
text: "今日の運勢",
|
|
202
|
+
type: "text"
|
|
203
203
|
},
|
|
204
204
|
{
|
|
205
|
-
|
|
206
|
-
text: starText,
|
|
205
|
+
margin: "md",
|
|
207
206
|
size: "xxl",
|
|
208
|
-
|
|
207
|
+
text: starText,
|
|
208
|
+
type: "text"
|
|
209
209
|
}
|
|
210
210
|
];
|
|
211
211
|
if (message) contents.push({
|
|
212
|
-
|
|
212
|
+
margin: "sm",
|
|
213
213
|
text: message,
|
|
214
|
-
|
|
215
|
-
|
|
214
|
+
type: "text",
|
|
215
|
+
wrap: true
|
|
216
216
|
});
|
|
217
217
|
if (luckyColor || luckyItem) contents.push({
|
|
218
|
-
|
|
219
|
-
|
|
218
|
+
margin: "md",
|
|
219
|
+
type: "separator"
|
|
220
220
|
});
|
|
221
221
|
if (luckyColor) contents.push({
|
|
222
|
-
type: "box",
|
|
223
|
-
layout: "horizontal",
|
|
224
|
-
margin: "md",
|
|
225
222
|
contents: [{
|
|
226
223
|
type: "text",
|
|
227
224
|
text: "ラッキーカラー",
|
|
@@ -233,12 +230,12 @@ var FlexTool = class extends Tool {
|
|
|
233
230
|
text: luckyColor,
|
|
234
231
|
size: "sm",
|
|
235
232
|
align: "end"
|
|
236
|
-
}]
|
|
233
|
+
}],
|
|
234
|
+
layout: "horizontal",
|
|
235
|
+
margin: "md",
|
|
236
|
+
type: "box"
|
|
237
237
|
});
|
|
238
238
|
if (luckyItem) contents.push({
|
|
239
|
-
type: "box",
|
|
240
|
-
layout: "horizontal",
|
|
241
|
-
margin: luckyColor ? "sm" : "md",
|
|
242
239
|
contents: [{
|
|
243
240
|
type: "text",
|
|
244
241
|
text: "ラッキーアイテム",
|
|
@@ -250,44 +247,47 @@ var FlexTool = class extends Tool {
|
|
|
250
247
|
text: luckyItem,
|
|
251
248
|
size: "sm",
|
|
252
249
|
align: "end"
|
|
253
|
-
}]
|
|
250
|
+
}],
|
|
251
|
+
layout: "horizontal",
|
|
252
|
+
margin: luckyColor ? "sm" : "md",
|
|
253
|
+
type: "box"
|
|
254
254
|
});
|
|
255
255
|
return {
|
|
256
|
-
type: "bubble",
|
|
257
|
-
size: "kilo",
|
|
258
256
|
body: {
|
|
259
257
|
type: "box",
|
|
260
258
|
layout: "vertical",
|
|
261
259
|
paddingAll: "lg",
|
|
262
260
|
contents
|
|
263
|
-
}
|
|
261
|
+
},
|
|
262
|
+
size: "kilo",
|
|
263
|
+
type: "bubble"
|
|
264
264
|
};
|
|
265
265
|
}
|
|
266
266
|
buildInfoCard(data) {
|
|
267
267
|
const title = String(data.title ?? "お知らせ");
|
|
268
268
|
const body = String(data.body ?? "");
|
|
269
269
|
const contents = [{
|
|
270
|
-
|
|
270
|
+
size: "lg",
|
|
271
271
|
text: title,
|
|
272
|
-
|
|
273
|
-
|
|
272
|
+
type: "text",
|
|
273
|
+
weight: "bold"
|
|
274
274
|
}, {
|
|
275
|
-
|
|
276
|
-
|
|
275
|
+
margin: "md",
|
|
276
|
+
type: "separator"
|
|
277
277
|
}];
|
|
278
278
|
if (body) contents.push({
|
|
279
|
-
|
|
279
|
+
margin: "md",
|
|
280
280
|
text: body,
|
|
281
|
-
|
|
282
|
-
|
|
281
|
+
type: "text",
|
|
282
|
+
wrap: true
|
|
283
283
|
});
|
|
284
284
|
return {
|
|
285
|
-
type: "bubble",
|
|
286
285
|
body: {
|
|
287
286
|
type: "box",
|
|
288
287
|
layout: "vertical",
|
|
289
288
|
contents
|
|
290
|
-
}
|
|
289
|
+
},
|
|
290
|
+
type: "bubble"
|
|
291
291
|
};
|
|
292
292
|
}
|
|
293
293
|
buildActionButtons(data) {
|
|
@@ -295,24 +295,23 @@ var FlexTool = class extends Tool {
|
|
|
295
295
|
const buttons = data.buttons ?? [];
|
|
296
296
|
if (buttons.length === 0) buttons.push({
|
|
297
297
|
label: "はい",
|
|
298
|
-
|
|
299
|
-
|
|
298
|
+
style: "primary",
|
|
299
|
+
text: "はい"
|
|
300
300
|
}, {
|
|
301
301
|
label: "いいえ",
|
|
302
|
-
|
|
303
|
-
|
|
302
|
+
style: "secondary",
|
|
303
|
+
text: "いいえ"
|
|
304
304
|
});
|
|
305
305
|
const buttonContents = buttons.map((btn) => ({
|
|
306
|
-
type: "button",
|
|
307
|
-
style: String(btn.style ?? "primary"),
|
|
308
306
|
action: {
|
|
309
307
|
type: "message",
|
|
310
308
|
label: String(btn.label ?? ""),
|
|
311
309
|
text: String(btn.text ?? btn.label ?? "")
|
|
312
|
-
}
|
|
310
|
+
},
|
|
311
|
+
style: String(btn.style ?? "primary"),
|
|
312
|
+
type: "button"
|
|
313
313
|
}));
|
|
314
314
|
return {
|
|
315
|
-
type: "bubble",
|
|
316
315
|
body: {
|
|
317
316
|
type: "box",
|
|
318
317
|
layout: "vertical",
|
|
@@ -328,7 +327,8 @@ var FlexTool = class extends Tool {
|
|
|
328
327
|
layout: "vertical",
|
|
329
328
|
spacing: "sm",
|
|
330
329
|
contents: buttonContents
|
|
331
|
-
}
|
|
330
|
+
},
|
|
331
|
+
type: "bubble"
|
|
332
332
|
};
|
|
333
333
|
}
|
|
334
334
|
buildReceipt(data) {
|
|
@@ -336,17 +336,14 @@ var FlexTool = class extends Tool {
|
|
|
336
336
|
const items = data.items ?? [];
|
|
337
337
|
const total = data.total ? String(data.total) : null;
|
|
338
338
|
const contents = [{
|
|
339
|
-
type: "text",
|
|
340
339
|
text: `💰 ${title}`,
|
|
340
|
+
type: "text",
|
|
341
341
|
weight: "bold"
|
|
342
342
|
}, {
|
|
343
|
-
|
|
344
|
-
|
|
343
|
+
margin: "lg",
|
|
344
|
+
type: "separator"
|
|
345
345
|
}];
|
|
346
346
|
for (const item of items) contents.push({
|
|
347
|
-
type: "box",
|
|
348
|
-
layout: "horizontal",
|
|
349
|
-
margin: "md",
|
|
350
347
|
contents: [{
|
|
351
348
|
type: "text",
|
|
352
349
|
text: String(item.name ?? ""),
|
|
@@ -355,15 +352,15 @@ var FlexTool = class extends Tool {
|
|
|
355
352
|
type: "text",
|
|
356
353
|
text: String(item.value ?? ""),
|
|
357
354
|
align: "end"
|
|
358
|
-
}]
|
|
355
|
+
}],
|
|
356
|
+
layout: "horizontal",
|
|
357
|
+
margin: "md",
|
|
358
|
+
type: "box"
|
|
359
359
|
});
|
|
360
360
|
if (total) contents.push({
|
|
361
|
-
|
|
362
|
-
|
|
361
|
+
margin: "lg",
|
|
362
|
+
type: "separator"
|
|
363
363
|
}, {
|
|
364
|
-
type: "box",
|
|
365
|
-
layout: "horizontal",
|
|
366
|
-
margin: "md",
|
|
367
364
|
contents: [{
|
|
368
365
|
type: "text",
|
|
369
366
|
text: "合計",
|
|
@@ -373,15 +370,18 @@ var FlexTool = class extends Tool {
|
|
|
373
370
|
text: total,
|
|
374
371
|
weight: "bold",
|
|
375
372
|
align: "end"
|
|
376
|
-
}]
|
|
373
|
+
}],
|
|
374
|
+
layout: "horizontal",
|
|
375
|
+
margin: "md",
|
|
376
|
+
type: "box"
|
|
377
377
|
});
|
|
378
378
|
return {
|
|
379
|
-
type: "bubble",
|
|
380
379
|
body: {
|
|
381
380
|
type: "box",
|
|
382
381
|
layout: "vertical",
|
|
383
382
|
contents
|
|
384
|
-
}
|
|
383
|
+
},
|
|
384
|
+
type: "bubble"
|
|
385
385
|
};
|
|
386
386
|
}
|
|
387
387
|
buildMorningSummary(data) {
|
|
@@ -392,51 +392,43 @@ var FlexTool = class extends Tool {
|
|
|
392
392
|
const schedule = data.schedule ?? [];
|
|
393
393
|
const headerColor = String(data.header_color ?? "#1DB446");
|
|
394
394
|
const headerContents = [{
|
|
395
|
-
type: "text",
|
|
396
|
-
text: greeting,
|
|
397
395
|
color: "#ffffff",
|
|
398
|
-
|
|
399
|
-
|
|
396
|
+
size: "lg",
|
|
397
|
+
text: greeting,
|
|
398
|
+
type: "text",
|
|
399
|
+
weight: "bold"
|
|
400
400
|
}];
|
|
401
401
|
if (date) headerContents.push({
|
|
402
|
-
type: "text",
|
|
403
|
-
text: date,
|
|
404
402
|
color: "#ffffff",
|
|
405
|
-
size: "sm"
|
|
403
|
+
size: "sm",
|
|
404
|
+
text: date,
|
|
405
|
+
type: "text"
|
|
406
406
|
});
|
|
407
407
|
const bodyContents = [];
|
|
408
408
|
if (weather) bodyContents.push({
|
|
409
|
-
type: "text",
|
|
410
409
|
text: weather,
|
|
410
|
+
type: "text",
|
|
411
411
|
weight: "bold"
|
|
412
412
|
});
|
|
413
413
|
if (advice) bodyContents.push({
|
|
414
|
-
|
|
415
|
-
text: advice,
|
|
414
|
+
color: "#666666",
|
|
416
415
|
size: "sm",
|
|
417
|
-
|
|
416
|
+
text: advice,
|
|
417
|
+
type: "text"
|
|
418
418
|
});
|
|
419
419
|
if (schedule.length > 0) {
|
|
420
420
|
bodyContents.push({
|
|
421
|
-
|
|
422
|
-
|
|
421
|
+
margin: "md",
|
|
422
|
+
type: "separator"
|
|
423
423
|
});
|
|
424
424
|
for (const line of schedule) bodyContents.push({
|
|
425
|
-
type: "text",
|
|
426
|
-
text: line,
|
|
427
425
|
margin: "md",
|
|
426
|
+
text: line,
|
|
427
|
+
type: "text",
|
|
428
428
|
wrap: true
|
|
429
429
|
});
|
|
430
430
|
}
|
|
431
431
|
return {
|
|
432
|
-
type: "bubble",
|
|
433
|
-
header: {
|
|
434
|
-
type: "box",
|
|
435
|
-
layout: "vertical",
|
|
436
|
-
backgroundColor: headerColor,
|
|
437
|
-
paddingAll: "lg",
|
|
438
|
-
contents: headerContents
|
|
439
|
-
},
|
|
440
432
|
body: {
|
|
441
433
|
type: "box",
|
|
442
434
|
layout: "vertical",
|
|
@@ -445,7 +437,15 @@ var FlexTool = class extends Tool {
|
|
|
445
437
|
type: "text",
|
|
446
438
|
text: "良い一日を!"
|
|
447
439
|
}]
|
|
448
|
-
}
|
|
440
|
+
},
|
|
441
|
+
header: {
|
|
442
|
+
type: "box",
|
|
443
|
+
layout: "vertical",
|
|
444
|
+
backgroundColor: headerColor,
|
|
445
|
+
paddingAll: "lg",
|
|
446
|
+
contents: headerContents
|
|
447
|
+
},
|
|
448
|
+
type: "bubble"
|
|
449
449
|
};
|
|
450
450
|
}
|
|
451
451
|
buildHydration(data) {
|
|
@@ -456,8 +456,6 @@ var FlexTool = class extends Tool {
|
|
|
456
456
|
const buttonLabel = String(data.button_label ?? "飲んだ!");
|
|
457
457
|
const buttonText = String(data.button_text ?? "水飲んだ");
|
|
458
458
|
return {
|
|
459
|
-
type: "bubble",
|
|
460
|
-
size: "kilo",
|
|
461
459
|
body: {
|
|
462
460
|
type: "box",
|
|
463
461
|
layout: "vertical",
|
|
@@ -484,23 +482,25 @@ var FlexTool = class extends Tool {
|
|
|
484
482
|
text: buttonText
|
|
485
483
|
}
|
|
486
484
|
}]
|
|
487
|
-
}
|
|
485
|
+
},
|
|
486
|
+
size: "kilo",
|
|
487
|
+
type: "bubble"
|
|
488
488
|
};
|
|
489
489
|
}
|
|
490
490
|
buildCustom(data) {
|
|
491
491
|
const bubbles = data.bubbles;
|
|
492
492
|
if (Array.isArray(bubbles) && bubbles.length > 0) return {
|
|
493
|
-
|
|
494
|
-
|
|
493
|
+
contents: bubbles,
|
|
494
|
+
type: "carousel"
|
|
495
495
|
};
|
|
496
496
|
const rawContents = data.contents;
|
|
497
497
|
if (Array.isArray(rawContents) && rawContents.length > 0) return {
|
|
498
|
-
type: "bubble",
|
|
499
498
|
body: {
|
|
500
499
|
type: "box",
|
|
501
500
|
layout: "vertical",
|
|
502
501
|
contents: rawContents
|
|
503
|
-
}
|
|
502
|
+
},
|
|
503
|
+
type: "bubble"
|
|
504
504
|
};
|
|
505
505
|
const title = data.title ? String(data.title) : null;
|
|
506
506
|
const body = data.body ? String(data.body) : null;
|
|
@@ -508,16 +508,16 @@ var FlexTool = class extends Tool {
|
|
|
508
508
|
const headerColor = data.header_color ? String(data.header_color) : null;
|
|
509
509
|
if (buttons.length === 0 && data.button_label) buttons = [{
|
|
510
510
|
label: String(data.button_label),
|
|
511
|
-
|
|
512
|
-
|
|
511
|
+
style: data.button_style ?? "primary",
|
|
512
|
+
text: String(data.button_text ?? data.button_label)
|
|
513
513
|
}];
|
|
514
514
|
if (!title && !body && buttons.length === 0) throw new Error("custom template requires 'contents' array, or at least one of: title, body, buttons");
|
|
515
515
|
const bodyContents = [];
|
|
516
516
|
if (title) bodyContents.push({
|
|
517
|
-
|
|
517
|
+
size: "lg",
|
|
518
518
|
text: title,
|
|
519
|
-
|
|
520
|
-
|
|
519
|
+
type: "text",
|
|
520
|
+
weight: "bold"
|
|
521
521
|
});
|
|
522
522
|
if (body) {
|
|
523
523
|
if (title) bodyContents.push({
|
|
@@ -525,14 +525,13 @@ var FlexTool = class extends Tool {
|
|
|
525
525
|
margin: "md"
|
|
526
526
|
});
|
|
527
527
|
bodyContents.push({
|
|
528
|
-
|
|
528
|
+
margin: title ? "md" : void 0,
|
|
529
529
|
text: body,
|
|
530
|
-
|
|
531
|
-
|
|
530
|
+
type: "text",
|
|
531
|
+
wrap: true
|
|
532
532
|
});
|
|
533
533
|
}
|
|
534
534
|
const bubble = {
|
|
535
|
-
type: "bubble",
|
|
536
535
|
body: {
|
|
537
536
|
type: "box",
|
|
538
537
|
layout: "vertical",
|
|
@@ -540,28 +539,26 @@ var FlexTool = class extends Tool {
|
|
|
540
539
|
type: "text",
|
|
541
540
|
text: " "
|
|
542
541
|
}]
|
|
543
|
-
}
|
|
542
|
+
},
|
|
543
|
+
type: "bubble"
|
|
544
544
|
};
|
|
545
545
|
if (headerColor && title) {
|
|
546
546
|
bubble.header = {
|
|
547
|
-
type: "box",
|
|
548
|
-
layout: "vertical",
|
|
549
547
|
backgroundColor: headerColor,
|
|
550
|
-
paddingAll: "lg",
|
|
551
548
|
contents: [{
|
|
552
549
|
type: "text",
|
|
553
550
|
text: title,
|
|
554
551
|
color: "#ffffff",
|
|
555
552
|
weight: "bold",
|
|
556
553
|
size: "lg"
|
|
557
|
-
}]
|
|
554
|
+
}],
|
|
555
|
+
layout: "vertical",
|
|
556
|
+
paddingAll: "lg",
|
|
557
|
+
type: "box"
|
|
558
558
|
};
|
|
559
559
|
bodyContents.shift();
|
|
560
560
|
}
|
|
561
561
|
if (buttons.length > 0) bubble.footer = {
|
|
562
|
-
type: "box",
|
|
563
|
-
layout: "vertical",
|
|
564
|
-
spacing: "sm",
|
|
565
562
|
contents: buttons.map((btn) => ({
|
|
566
563
|
type: "button",
|
|
567
564
|
style: String(btn.style ?? "primary"),
|
|
@@ -570,7 +567,10 @@ var FlexTool = class extends Tool {
|
|
|
570
567
|
label: String(btn.label ?? ""),
|
|
571
568
|
text: String(btn.text ?? btn.label ?? "")
|
|
572
569
|
}
|
|
573
|
-
}))
|
|
570
|
+
})),
|
|
571
|
+
layout: "vertical",
|
|
572
|
+
spacing: "sm",
|
|
573
|
+
type: "box"
|
|
574
574
|
};
|
|
575
575
|
return bubble;
|
|
576
576
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"flex.mjs","names":[],"sources":["../../../src/agent/tools/flex.ts"],"sourcesContent":["import { Tool } from \"./base.js\";\n\n/**\n * Tool for building LINE Flex Messages from structured data.\n *\n * The LLM calls this tool with a template name and data object,\n * and the tool returns valid Flex JSON that line.ts parseMessage()\n * will detect and send as a Flex Message.\n */\nexport class FlexTool extends Tool {\n readonly name = \"flex_message\";\n readonly description =\n \"Build a LINE Flex Message from a template. Returns JSON that will be rendered as a rich card in LINE. Use this instead of outputting raw JSON.\";\n readonly parameters = {\n type: \"object\",\n properties: {\n template: {\n type: \"string\",\n description:\n \"Template name. Available: fortune, info_card, action_buttons, receipt, morning_summary, hydration, custom.\",\n },\n data: {\n type: \"object\",\n description: \"Template-specific data. See each template for fields.\",\n properties: {\n // fortune\n sign: { type: \"string\", description: \"Zodiac sign with emoji (e.g. '♍ 乙女座')\" },\n stars: { type: \"integer\", description: \"1-5 star rating\" },\n message: { type: \"string\", description: \"Fortune message\" },\n lucky_color: { type: \"string\", description: \"Lucky color name\" },\n lucky_item: { type: \"string\", description: \"Lucky item name\" },\n // info_card\n title: { type: \"string\", description: \"Card title\" },\n body: { type: \"string\", description: \"Card body text\" },\n // action_buttons\n prompt: { type: \"string\", description: \"Question or prompt text\" },\n buttons: {\n type: \"array\",\n items: {\n type: \"object\",\n properties: {\n label: { type: \"string\" },\n text: { type: \"string\" },\n style: { type: \"string\", enum: [\"primary\", \"secondary\", \"link\"] },\n },\n },\n description: \"Button definitions\",\n },\n // receipt\n items: {\n type: \"array\",\n items: {\n type: \"object\",\n properties: {\n name: { type: \"string\" },\n value: { type: \"string\" },\n },\n },\n description: \"Line items\",\n },\n total: { type: \"string\", description: \"Total amount\" },\n // morning_summary\n greeting: { type: \"string\", description: \"Greeting text (e.g. 'おはよう!')\" },\n date: { type: \"string\", description: \"Date string (e.g. '2月13日 木曜日')\" },\n weather: { type: \"string\", description: \"Weather info (e.g. '東京 12°C 曇り')\" },\n advice: { type: \"string\", description: \"Short advice (e.g. 'コートでOK')\" },\n schedule: {\n type: \"array\",\n items: { type: \"string\" },\n description: \"Schedule/reminder lines\",\n },\n header_color: { type: \"string\", description: \"Header background color hex (default: #1DB446)\" },\n // hydration\n current: { type: \"integer\", description: \"Current count (e.g. glasses drunk)\" },\n goal: { type: \"integer\", description: \"Goal count\" },\n unit: { type: \"string\", description: \"Unit label (default: 杯)\" },\n button_label: { type: \"string\", description: \"Button label (default: '飲んだ!')\" },\n button_text: { type: \"string\", description: \"Button message text (default: '水飲んだ')\" },\n // custom\n contents: {\n type: \"array\",\n description: \"Raw Flex body contents array for custom template\",\n },\n bubbles: {\n type: \"array\",\n items: { type: \"object\" },\n description: \"Array of bubble objects for a carousel (horizontal swipeable cards). Each item should be a complete bubble with type, body, etc.\",\n },\n },\n },\n },\n required: [\"template\", \"data\"],\n };\n\n async execute(args: Record<string, unknown>): Promise<string> {\n const template = String(args.template);\n const data = (args.data ?? {}) as Record<string, unknown>;\n\n try {\n let flex: Record<string, unknown>;\n\n switch (template) {\n case \"fortune\":\n flex = this.buildFortune(data);\n break;\n case \"info_card\":\n flex = this.buildInfoCard(data);\n break;\n case \"action_buttons\":\n flex = this.buildActionButtons(data);\n break;\n case \"receipt\":\n flex = this.buildReceipt(data);\n break;\n case \"morning_summary\":\n flex = this.buildMorningSummary(data);\n break;\n case \"hydration\":\n flex = this.buildHydration(data);\n break;\n case \"custom\":\n flex = this.buildCustom(data);\n break;\n default:\n return `Error: unknown template '${template}'. Use: fortune, info_card, action_buttons, receipt, morning_summary, hydration, custom.`;\n }\n\n const json = JSON.stringify(flex);\n return `${json}\\n\\n(Card sent automatically. Do NOT repeat the JSON. Just respond naturally.)`;\n } catch (err) {\n return `Error building flex message: ${err instanceof Error ? err.message : err}`;\n }\n }\n\n private buildFortune(data: Record<string, unknown>): Record<string, unknown> {\n const sign = String(data.sign ?? \"♈ 牡羊座\");\n const stars = Math.max(1, Math.min(5, Number(data.stars ?? 3)));\n const message = String(data.message ?? \"\");\n const luckyColor = data.lucky_color ? String(data.lucky_color) : null;\n const luckyItem = data.lucky_item ? String(data.lucky_item) : null;\n\n const starText = \"★\".repeat(stars) + \"☆\".repeat(5 - stars);\n\n const contents: Record<string, unknown>[] = [\n { type: \"text\", text: sign, weight: \"bold\", size: \"xl\" },\n { type: \"text\", text: \"今日の運勢\", size: \"sm\", color: \"#666666\" },\n { type: \"text\", text: starText, size: \"xxl\", margin: \"md\" },\n ];\n\n if (message) {\n contents.push({\n type: \"text\",\n text: message,\n wrap: true,\n margin: \"sm\",\n });\n }\n\n if (luckyColor || luckyItem) {\n contents.push({ type: \"separator\", margin: \"md\" });\n }\n\n if (luckyColor) {\n contents.push({\n type: \"box\",\n layout: \"horizontal\",\n margin: \"md\",\n contents: [\n { type: \"text\", text: \"ラッキーカラー\", size: \"sm\", color: \"#228B22\", flex: 0 },\n { type: \"text\", text: luckyColor, size: \"sm\", align: \"end\" },\n ],\n });\n }\n\n if (luckyItem) {\n contents.push({\n type: \"box\",\n layout: \"horizontal\",\n margin: luckyColor ? \"sm\" : \"md\",\n contents: [\n { type: \"text\", text: \"ラッキーアイテム\", size: \"sm\", color: \"#228B22\", flex: 0 },\n { type: \"text\", text: luckyItem, size: \"sm\", align: \"end\" },\n ],\n });\n }\n\n return {\n type: \"bubble\",\n size: \"kilo\",\n body: {\n type: \"box\",\n layout: \"vertical\",\n paddingAll: \"lg\",\n contents,\n },\n };\n }\n\n private buildInfoCard(data: Record<string, unknown>): Record<string, unknown> {\n const title = String(data.title ?? \"お知らせ\");\n const body = String(data.body ?? \"\");\n\n const contents: Record<string, unknown>[] = [\n { type: \"text\", text: title, weight: \"bold\", size: \"lg\" },\n { type: \"separator\", margin: \"md\" },\n ];\n\n if (body) {\n contents.push({\n type: \"text\",\n text: body,\n wrap: true,\n margin: \"md\",\n });\n }\n\n return {\n type: \"bubble\",\n body: {\n type: \"box\",\n layout: \"vertical\",\n contents,\n },\n };\n }\n\n private buildActionButtons(data: Record<string, unknown>): Record<string, unknown> {\n const prompt = String(data.prompt ?? \"選択してください\");\n const buttons = (data.buttons ?? []) as Array<Record<string, unknown>>;\n\n if (buttons.length === 0) {\n // Default yes/no\n buttons.push(\n { label: \"はい\", text: \"はい\", style: \"primary\" },\n { label: \"いいえ\", text: \"いいえ\", style: \"secondary\" },\n );\n }\n\n const buttonContents = buttons.map((btn) => ({\n type: \"button\",\n style: String(btn.style ?? \"primary\"),\n action: {\n type: \"message\",\n label: String(btn.label ?? \"\"),\n text: String(btn.text ?? btn.label ?? \"\"),\n },\n }));\n\n return {\n type: \"bubble\",\n body: {\n type: \"box\",\n layout: \"vertical\",\n contents: [\n { type: \"text\", text: prompt, weight: \"bold\", wrap: true },\n ],\n },\n footer: {\n type: \"box\",\n layout: \"vertical\",\n spacing: \"sm\",\n contents: buttonContents,\n },\n };\n }\n\n private buildReceipt(data: Record<string, unknown>): Record<string, unknown> {\n const title = String(data.title ?? \"明細\");\n const items = (data.items ?? []) as Array<Record<string, unknown>>;\n const total = data.total ? String(data.total) : null;\n\n const contents: Record<string, unknown>[] = [\n { type: \"text\", text: `💰 ${title}`, weight: \"bold\" },\n { type: \"separator\", margin: \"lg\" },\n ];\n\n for (const item of items) {\n contents.push({\n type: \"box\",\n layout: \"horizontal\",\n margin: \"md\",\n contents: [\n { type: \"text\", text: String(item.name ?? \"\"), flex: 0 },\n { type: \"text\", text: String(item.value ?? \"\"), align: \"end\" },\n ],\n });\n }\n\n if (total) {\n contents.push(\n { type: \"separator\", margin: \"lg\" },\n {\n type: \"box\",\n layout: \"horizontal\",\n margin: \"md\",\n contents: [\n { type: \"text\", text: \"合計\", weight: \"bold\" },\n { type: \"text\", text: total, weight: \"bold\", align: \"end\" },\n ],\n },\n );\n }\n\n return {\n type: \"bubble\",\n body: {\n type: \"box\",\n layout: \"vertical\",\n contents,\n },\n };\n }\n\n private buildMorningSummary(data: Record<string, unknown>): Record<string, unknown> {\n const greeting = String(data.greeting ?? \"おはよう!\");\n const date = String(data.date ?? \"\");\n const weather = data.weather ? String(data.weather) : null;\n const advice = data.advice ? String(data.advice) : null;\n const schedule = (data.schedule ?? []) as string[];\n const headerColor = String(data.header_color ?? \"#1DB446\");\n\n const headerContents: Record<string, unknown>[] = [\n { type: \"text\", text: greeting, color: \"#ffffff\", weight: \"bold\", size: \"lg\" },\n ];\n if (date) {\n headerContents.push({ type: \"text\", text: date, color: \"#ffffff\", size: \"sm\" });\n }\n\n const bodyContents: Record<string, unknown>[] = [];\n\n if (weather) {\n bodyContents.push({ type: \"text\", text: weather, weight: \"bold\" });\n }\n if (advice) {\n bodyContents.push({ type: \"text\", text: advice, size: \"sm\", color: \"#666666\" });\n }\n\n if (schedule.length > 0) {\n bodyContents.push({ type: \"separator\", margin: \"md\" });\n for (const line of schedule) {\n bodyContents.push({ type: \"text\", text: line, margin: \"md\", wrap: true });\n }\n }\n\n return {\n type: \"bubble\",\n header: {\n type: \"box\",\n layout: \"vertical\",\n backgroundColor: headerColor,\n paddingAll: \"lg\",\n contents: headerContents,\n },\n body: {\n type: \"box\",\n layout: \"vertical\",\n paddingAll: \"lg\",\n contents: bodyContents.length > 0 ? bodyContents : [{ type: \"text\", text: \"良い一日を!\" }],\n },\n };\n }\n\n private buildHydration(data: Record<string, unknown>): Record<string, unknown> {\n const title = String(data.title ?? \"水飲んだ?\");\n const current = Number(data.current ?? 0);\n const goal = Number(data.goal ?? 8);\n const unit = String(data.unit ?? \"杯\");\n const buttonLabel = String(data.button_label ?? \"飲んだ!\");\n const buttonText = String(data.button_text ?? \"水飲んだ\");\n\n return {\n type: \"bubble\",\n size: \"kilo\",\n body: {\n type: \"box\",\n layout: \"vertical\",\n contents: [\n { type: \"text\", text: title, size: \"xl\" },\n { type: \"text\", text: `今日: ${current}${unit} / ${goal}${unit}`, color: \"#666666\" },\n ],\n },\n footer: {\n type: \"box\",\n layout: \"horizontal\",\n contents: [\n {\n type: \"button\",\n style: \"primary\",\n color: \"#00B9ED\",\n action: { type: \"message\", label: buttonLabel, text: buttonText },\n },\n ],\n },\n };\n }\n\n private buildCustom(data: Record<string, unknown>): Record<string, unknown> {\n // Carousel: array of bubble objects → horizontal swipeable cards\n const bubbles = data.bubbles as unknown[];\n if (Array.isArray(bubbles) && bubbles.length > 0) {\n return {\n type: \"carousel\",\n contents: bubbles,\n };\n }\n\n // If raw contents array is provided, use it directly as body contents\n const rawContents = data.contents as unknown[];\n if (Array.isArray(rawContents) && rawContents.length > 0) {\n return {\n type: \"bubble\",\n body: {\n type: \"box\",\n layout: \"vertical\",\n contents: rawContents,\n },\n };\n }\n\n // Fallback: auto-build a card from common fields (title, body, buttons, header_color)\n const title = data.title ? String(data.title) : null;\n const body = data.body ? String(data.body) : null;\n let buttons = Array.isArray(data.buttons) ? data.buttons as Array<Record<string, unknown>> : [];\n const headerColor = data.header_color ? String(data.header_color) : null;\n\n // Support flat button_label/button_text shorthand (like hydration template)\n if (buttons.length === 0 && data.button_label) {\n buttons = [{\n label: String(data.button_label),\n text: String(data.button_text ?? data.button_label),\n style: data.button_style ?? \"primary\",\n }];\n }\n\n if (!title && !body && buttons.length === 0) {\n throw new Error(\"custom template requires 'contents' array, or at least one of: title, body, buttons\");\n }\n\n const bodyContents: Record<string, unknown>[] = [];\n\n if (title) {\n bodyContents.push({ type: \"text\", text: title, weight: \"bold\", size: \"lg\" });\n }\n if (body) {\n if (title) bodyContents.push({ type: \"separator\", margin: \"md\" });\n bodyContents.push({ type: \"text\", text: body, wrap: true, margin: title ? \"md\" : undefined });\n }\n\n const bubble: Record<string, unknown> = {\n type: \"bubble\",\n body: {\n type: \"box\",\n layout: \"vertical\",\n contents: bodyContents.length > 0 ? bodyContents : [{ type: \"text\", text: \" \" }],\n },\n };\n\n // Add colored header if specified\n if (headerColor && title) {\n bubble.header = {\n type: \"box\",\n layout: \"vertical\",\n backgroundColor: headerColor,\n paddingAll: \"lg\",\n contents: [\n { type: \"text\", text: title, color: \"#ffffff\", weight: \"bold\", size: \"lg\" },\n ],\n };\n // Remove title from body since it's in the header now\n bodyContents.shift();\n }\n\n // Add buttons as footer\n if (buttons.length > 0) {\n bubble.footer = {\n type: \"box\",\n layout: \"vertical\",\n spacing: \"sm\",\n contents: buttons.map((btn) => ({\n type: \"button\",\n style: String(btn.style ?? \"primary\"),\n action: {\n type: \"message\",\n label: String(btn.label ?? \"\"),\n text: String(btn.text ?? btn.label ?? \"\"),\n },\n })),\n };\n }\n\n return bubble;\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"flex.mjs","names":[],"sources":["../../../src/agent/tools/flex.ts"],"sourcesContent":["import { Tool } from \"./base.js\";\n\n/**\n * Tool for building LINE Flex Messages from structured data.\n *\n * The LLM calls this tool with a template name and data object,\n * and the tool returns valid Flex JSON that line.ts parseMessage()\n * will detect and send as a Flex Message.\n */\nexport class FlexTool extends Tool {\n readonly name = \"flex_message\";\n readonly description =\n \"Build a LINE Flex Message from a template. Returns JSON that will be rendered as a rich card in LINE. Use this instead of outputting raw JSON.\";\n readonly parameters = {\n properties: {\n template: {\n type: \"string\",\n description:\n \"Template name. Available: fortune, info_card, action_buttons, receipt, morning_summary, hydration, custom.\",\n },\n data: {\n type: \"object\",\n description: \"Template-specific data. See each template for fields.\",\n properties: {\n // fortune\n sign: {\n type: \"string\",\n description: \"Zodiac sign with emoji (e.g. '♍ 乙女座')\",\n },\n stars: { type: \"integer\", description: \"1-5 star rating\" },\n message: { type: \"string\", description: \"Fortune message\" },\n lucky_color: { type: \"string\", description: \"Lucky color name\" },\n lucky_item: { type: \"string\", description: \"Lucky item name\" },\n // info_card\n title: { type: \"string\", description: \"Card title\" },\n body: { type: \"string\", description: \"Card body text\" },\n // action_buttons\n prompt: { type: \"string\", description: \"Question or prompt text\" },\n buttons: {\n type: \"array\",\n items: {\n type: \"object\",\n properties: {\n label: { type: \"string\" },\n text: { type: \"string\" },\n style: {\n type: \"string\",\n enum: [\"primary\", \"secondary\", \"link\"],\n },\n },\n },\n description: \"Button definitions\",\n },\n // receipt\n items: {\n type: \"array\",\n items: {\n type: \"object\",\n properties: {\n name: { type: \"string\" },\n value: { type: \"string\" },\n },\n },\n description: \"Line items\",\n },\n total: { type: \"string\", description: \"Total amount\" },\n // morning_summary\n greeting: {\n type: \"string\",\n description: \"Greeting text (e.g. 'おはよう!')\",\n },\n date: {\n type: \"string\",\n description: \"Date string (e.g. '2月13日 木曜日')\",\n },\n weather: {\n type: \"string\",\n description: \"Weather info (e.g. '東京 12°C 曇り')\",\n },\n advice: {\n type: \"string\",\n description: \"Short advice (e.g. 'コートでOK')\",\n },\n schedule: {\n type: \"array\",\n items: { type: \"string\" },\n description: \"Schedule/reminder lines\",\n },\n header_color: {\n type: \"string\",\n description: \"Header background color hex (default: #1DB446)\",\n },\n // hydration\n current: {\n type: \"integer\",\n description: \"Current count (e.g. glasses drunk)\",\n },\n goal: { type: \"integer\", description: \"Goal count\" },\n unit: { type: \"string\", description: \"Unit label (default: 杯)\" },\n button_label: {\n type: \"string\",\n description: \"Button label (default: '飲んだ!')\",\n },\n button_text: {\n type: \"string\",\n description: \"Button message text (default: '水飲んだ')\",\n },\n // custom\n contents: {\n type: \"array\",\n description: \"Raw Flex body contents array for custom template\",\n },\n bubbles: {\n type: \"array\",\n items: { type: \"object\" },\n description:\n \"Array of bubble objects for a carousel (horizontal swipeable cards). Each item should be a complete bubble with type, body, etc.\",\n },\n },\n },\n },\n required: [\"template\", \"data\"],\n type: \"object\",\n };\n\n async execute(args: Record<string, unknown>): Promise<string> {\n const template = String(args.template);\n const data = (args.data ?? {}) as Record<string, unknown>;\n\n try {\n let flex: Record<string, unknown>;\n\n switch (template) {\n case \"fortune\": {\n flex = this.buildFortune(data);\n break;\n }\n case \"info_card\": {\n flex = this.buildInfoCard(data);\n break;\n }\n case \"action_buttons\": {\n flex = this.buildActionButtons(data);\n break;\n }\n case \"receipt\": {\n flex = this.buildReceipt(data);\n break;\n }\n case \"morning_summary\": {\n flex = this.buildMorningSummary(data);\n break;\n }\n case \"hydration\": {\n flex = this.buildHydration(data);\n break;\n }\n case \"custom\": {\n flex = this.buildCustom(data);\n break;\n }\n default: {\n return `Error: unknown template '${template}'. Use: fortune, info_card, action_buttons, receipt, morning_summary, hydration, custom.`;\n }\n }\n\n const json = JSON.stringify(flex);\n return `${json}\\n\\n(Card sent automatically. Do NOT repeat the JSON. Just respond naturally.)`;\n } catch (error) {\n return `Error building flex message: ${error instanceof Error ? error.message : error}`;\n }\n }\n\n private buildFortune(data: Record<string, unknown>): Record<string, unknown> {\n const sign = String(data.sign ?? \"♈ 牡羊座\");\n const stars = Math.max(1, Math.min(5, Number(data.stars ?? 3)));\n const message = String(data.message ?? \"\");\n const luckyColor = data.lucky_color ? String(data.lucky_color) : null;\n const luckyItem = data.lucky_item ? String(data.lucky_item) : null;\n\n const starText = \"★\".repeat(stars) + \"☆\".repeat(5 - stars);\n\n const contents: Record<string, unknown>[] = [\n { size: \"xl\", text: sign, type: \"text\", weight: \"bold\" },\n { color: \"#666666\", size: \"sm\", text: \"今日の運勢\", type: \"text\" },\n { margin: \"md\", size: \"xxl\", text: starText, type: \"text\" },\n ];\n\n if (message) {\n contents.push({\n margin: \"sm\",\n text: message,\n type: \"text\",\n wrap: true,\n });\n }\n\n if (luckyColor || luckyItem) {\n contents.push({ margin: \"md\", type: \"separator\" });\n }\n\n if (luckyColor) {\n contents.push({\n contents: [\n {\n type: \"text\",\n text: \"ラッキーカラー\",\n size: \"sm\",\n color: \"#228B22\",\n flex: 0,\n },\n { type: \"text\", text: luckyColor, size: \"sm\", align: \"end\" },\n ],\n layout: \"horizontal\",\n margin: \"md\",\n type: \"box\",\n });\n }\n\n if (luckyItem) {\n contents.push({\n contents: [\n {\n type: \"text\",\n text: \"ラッキーアイテム\",\n size: \"sm\",\n color: \"#228B22\",\n flex: 0,\n },\n { type: \"text\", text: luckyItem, size: \"sm\", align: \"end\" },\n ],\n layout: \"horizontal\",\n margin: luckyColor ? \"sm\" : \"md\",\n type: \"box\",\n });\n }\n\n return {\n body: {\n type: \"box\",\n layout: \"vertical\",\n paddingAll: \"lg\",\n contents,\n },\n size: \"kilo\",\n type: \"bubble\",\n };\n }\n\n private buildInfoCard(\n data: Record<string, unknown>\n ): Record<string, unknown> {\n const title = String(data.title ?? \"お知らせ\");\n const body = String(data.body ?? \"\");\n\n const contents: Record<string, unknown>[] = [\n { size: \"lg\", text: title, type: \"text\", weight: \"bold\" },\n { margin: \"md\", type: \"separator\" },\n ];\n\n if (body) {\n contents.push({\n margin: \"md\",\n text: body,\n type: \"text\",\n wrap: true,\n });\n }\n\n return {\n body: {\n type: \"box\",\n layout: \"vertical\",\n contents,\n },\n type: \"bubble\",\n };\n }\n\n private buildActionButtons(\n data: Record<string, unknown>\n ): Record<string, unknown> {\n const prompt = String(data.prompt ?? \"選択してください\");\n const buttons = (data.buttons ?? []) as Record<string, unknown>[];\n\n if (buttons.length === 0) {\n // Default yes/no\n buttons.push(\n { label: \"はい\", style: \"primary\", text: \"はい\" },\n { label: \"いいえ\", style: \"secondary\", text: \"いいえ\" }\n );\n }\n\n const buttonContents = buttons.map((btn) => ({\n action: {\n type: \"message\",\n label: String(btn.label ?? \"\"),\n text: String(btn.text ?? btn.label ?? \"\"),\n },\n style: String(btn.style ?? \"primary\"),\n type: \"button\",\n }));\n\n return {\n body: {\n type: \"box\",\n layout: \"vertical\",\n contents: [{ type: \"text\", text: prompt, weight: \"bold\", wrap: true }],\n },\n footer: {\n type: \"box\",\n layout: \"vertical\",\n spacing: \"sm\",\n contents: buttonContents,\n },\n type: \"bubble\",\n };\n }\n\n private buildReceipt(data: Record<string, unknown>): Record<string, unknown> {\n const title = String(data.title ?? \"明細\");\n const items = (data.items ?? []) as Record<string, unknown>[];\n const total = data.total ? String(data.total) : null;\n\n const contents: Record<string, unknown>[] = [\n { text: `💰 ${title}`, type: \"text\", weight: \"bold\" },\n { margin: \"lg\", type: \"separator\" },\n ];\n\n for (const item of items) {\n contents.push({\n contents: [\n { type: \"text\", text: String(item.name ?? \"\"), flex: 0 },\n { type: \"text\", text: String(item.value ?? \"\"), align: \"end\" },\n ],\n layout: \"horizontal\",\n margin: \"md\",\n type: \"box\",\n });\n }\n\n if (total) {\n contents.push(\n { margin: \"lg\", type: \"separator\" },\n {\n contents: [\n { type: \"text\", text: \"合計\", weight: \"bold\" },\n { type: \"text\", text: total, weight: \"bold\", align: \"end\" },\n ],\n layout: \"horizontal\",\n margin: \"md\",\n type: \"box\",\n }\n );\n }\n\n return {\n body: {\n type: \"box\",\n layout: \"vertical\",\n contents,\n },\n type: \"bubble\",\n };\n }\n\n private buildMorningSummary(\n data: Record<string, unknown>\n ): Record<string, unknown> {\n const greeting = String(data.greeting ?? \"おはよう!\");\n const date = String(data.date ?? \"\");\n const weather = data.weather ? String(data.weather) : null;\n const advice = data.advice ? String(data.advice) : null;\n const schedule = (data.schedule ?? []) as string[];\n const headerColor = String(data.header_color ?? \"#1DB446\");\n\n const headerContents: Record<string, unknown>[] = [\n {\n color: \"#ffffff\",\n size: \"lg\",\n text: greeting,\n type: \"text\",\n weight: \"bold\",\n },\n ];\n if (date) {\n headerContents.push({\n color: \"#ffffff\",\n size: \"sm\",\n text: date,\n type: \"text\",\n });\n }\n\n const bodyContents: Record<string, unknown>[] = [];\n\n if (weather) {\n bodyContents.push({ text: weather, type: \"text\", weight: \"bold\" });\n }\n if (advice) {\n bodyContents.push({\n color: \"#666666\",\n size: \"sm\",\n text: advice,\n type: \"text\",\n });\n }\n\n if (schedule.length > 0) {\n bodyContents.push({ margin: \"md\", type: \"separator\" });\n for (const line of schedule) {\n bodyContents.push({\n margin: \"md\",\n text: line,\n type: \"text\",\n wrap: true,\n });\n }\n }\n\n return {\n body: {\n type: \"box\",\n layout: \"vertical\",\n paddingAll: \"lg\",\n contents:\n bodyContents.length > 0\n ? bodyContents\n : [{ type: \"text\", text: \"良い一日を!\" }],\n },\n header: {\n type: \"box\",\n layout: \"vertical\",\n backgroundColor: headerColor,\n paddingAll: \"lg\",\n contents: headerContents,\n },\n type: \"bubble\",\n };\n }\n\n private buildHydration(\n data: Record<string, unknown>\n ): Record<string, unknown> {\n const title = String(data.title ?? \"水飲んだ?\");\n const current = Number(data.current ?? 0);\n const goal = Number(data.goal ?? 8);\n const unit = String(data.unit ?? \"杯\");\n const buttonLabel = String(data.button_label ?? \"飲んだ!\");\n const buttonText = String(data.button_text ?? \"水飲んだ\");\n\n return {\n body: {\n type: \"box\",\n layout: \"vertical\",\n contents: [\n { type: \"text\", text: title, size: \"xl\" },\n {\n type: \"text\",\n text: `今日: ${current}${unit} / ${goal}${unit}`,\n color: \"#666666\",\n },\n ],\n },\n footer: {\n type: \"box\",\n layout: \"horizontal\",\n contents: [\n {\n type: \"button\",\n style: \"primary\",\n color: \"#00B9ED\",\n action: { type: \"message\", label: buttonLabel, text: buttonText },\n },\n ],\n },\n size: \"kilo\",\n type: \"bubble\",\n };\n }\n\n private buildCustom(data: Record<string, unknown>): Record<string, unknown> {\n // Carousel: array of bubble objects → horizontal swipeable cards\n const bubbles = data.bubbles as unknown[];\n if (Array.isArray(bubbles) && bubbles.length > 0) {\n return {\n contents: bubbles,\n type: \"carousel\",\n };\n }\n\n // If raw contents array is provided, use it directly as body contents\n const rawContents = data.contents as unknown[];\n if (Array.isArray(rawContents) && rawContents.length > 0) {\n return {\n body: {\n type: \"box\",\n layout: \"vertical\",\n contents: rawContents,\n },\n type: \"bubble\",\n };\n }\n\n // Fallback: auto-build a card from common fields (title, body, buttons, header_color)\n const title = data.title ? String(data.title) : null;\n const body = data.body ? String(data.body) : null;\n let buttons = Array.isArray(data.buttons)\n ? (data.buttons as Record<string, unknown>[])\n : [];\n const headerColor = data.header_color ? String(data.header_color) : null;\n\n // Support flat button_label/button_text shorthand (like hydration template)\n if (buttons.length === 0 && data.button_label) {\n buttons = [\n {\n label: String(data.button_label),\n style: data.button_style ?? \"primary\",\n text: String(data.button_text ?? data.button_label),\n },\n ];\n }\n\n if (!title && !body && buttons.length === 0) {\n throw new Error(\n \"custom template requires 'contents' array, or at least one of: title, body, buttons\"\n );\n }\n\n const bodyContents: Record<string, unknown>[] = [];\n\n if (title) {\n bodyContents.push({\n size: \"lg\",\n text: title,\n type: \"text\",\n weight: \"bold\",\n });\n }\n if (body) {\n if (title) {\n bodyContents.push({ type: \"separator\", margin: \"md\" });\n }\n bodyContents.push({\n margin: title ? \"md\" : undefined,\n text: body,\n type: \"text\",\n wrap: true,\n });\n }\n\n const bubble: Record<string, unknown> = {\n body: {\n type: \"box\",\n layout: \"vertical\",\n contents:\n bodyContents.length > 0\n ? bodyContents\n : [{ type: \"text\", text: \" \" }],\n },\n type: \"bubble\",\n };\n\n // Add colored header if specified\n if (headerColor && title) {\n bubble.header = {\n backgroundColor: headerColor,\n contents: [\n {\n type: \"text\",\n text: title,\n color: \"#ffffff\",\n weight: \"bold\",\n size: \"lg\",\n },\n ],\n layout: \"vertical\",\n paddingAll: \"lg\",\n type: \"box\",\n };\n // Remove title from body since it's in the header now\n bodyContents.shift();\n }\n\n // Add buttons as footer\n if (buttons.length > 0) {\n bubble.footer = {\n contents: buttons.map((btn) => ({\n type: \"button\",\n style: String(btn.style ?? \"primary\"),\n action: {\n type: \"message\",\n label: String(btn.label ?? \"\"),\n text: String(btn.text ?? btn.label ?? \"\"),\n },\n })),\n layout: \"vertical\",\n spacing: \"sm\",\n type: \"box\",\n };\n }\n\n return bubble;\n }\n}\n"],"mappings":"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"}
|